private void updateNotificationState() {
   if (BuildConfig.DEBUG) Logger.log("SensorListener updateNotificationState");
   SharedPreferences prefs = getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS);
   NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
   if (prefs.getBoolean("notification", true)) {
     int goal = prefs.getInt("goal", 10000);
     Database db = Database.getInstance(this);
     int today_offset = db.getSteps(Util.getToday());
     db.close();
     Notification.Builder notificationBuilder = new Notification.Builder(this);
     if (steps > 0) {
       if (today_offset == Integer.MIN_VALUE) today_offset = -steps;
       notificationBuilder
           .setProgress(goal, today_offset + steps, false)
           .setContentText(
               today_offset + steps >= goal
                   ? getString(
                       R.string.goal_reached_notification,
                       NumberFormat.getInstance(Locale.getDefault())
                           .format((today_offset + steps)))
                   : getString(
                       R.string.notification_text,
                       NumberFormat.getInstance(Locale.getDefault())
                           .format((goal - today_offset - steps))));
     } else {
       notificationBuilder.setContentText(
           getString(R.string.your_progress_will_be_shown_here_soon));
     }
     boolean isPaused = prefs.contains("pauseCount");
     notificationBuilder
         .setPriority(Notification.PRIORITY_MIN)
         .setShowWhen(false)
         .setContentTitle(
             isPaused ? getString(R.string.ispaused) : getString(R.string.notification_title))
         .setContentIntent(
             PendingIntent.getActivity(
                 this,
                 0,
                 new Intent(this, Activity_Main.class),
                 PendingIntent.FLAG_UPDATE_CURRENT))
         .setSmallIcon(R.drawable.ic_notification)
         .addAction(
             isPaused ? R.drawable.ic_resume : R.drawable.ic_pause,
             isPaused ? getString(R.string.resume) : getString(R.string.pause),
             PendingIntent.getService(
                 this,
                 4,
                 new Intent(this, SensorListener.class).putExtra("action", ACTION_PAUSE),
                 PendingIntent.FLAG_UPDATE_CURRENT))
         .setOngoing(true);
     nm.notify(1, notificationBuilder.build());
   } else {
     nm.cancel(1);
   }
 }
  @Override
  public int onStartCommand(final Intent intent, int flags, int startId) {
    if (intent != null && ACTION_PAUSE.equals(intent.getStringExtra("action"))) {
      if (BuildConfig.DEBUG)
        Logger.log("onStartCommand action: " + intent.getStringExtra("action"));
      if (steps == 0) {
        Database db = Database.getInstance(this);
        steps = db.getCurrentSteps();
        db.close();
      }
      SharedPreferences prefs = getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS);
      if (prefs.contains("pauseCount")) { // resume counting
        int difference =
            steps - prefs.getInt("pauseCount", steps); // number of steps taken during the pause
        Database db = Database.getInstance(this);
        db.updateSteps(Util.getToday(), -difference);
        db.close();
        prefs.edit().remove("pauseCount").commit();
        updateNotificationState();
      } else { // pause counting
        // cancel restart
        ((AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE))
            .cancel(
                PendingIntent.getService(
                    getApplicationContext(),
                    2,
                    new Intent(this, SensorListener.class),
                    PendingIntent.FLAG_UPDATE_CURRENT));
        prefs.edit().putInt("pauseCount", steps).commit();
        updateNotificationState();
        stopSelf();
        return START_NOT_STICKY;
      }
    }

    // restart service every hour to get the current step count
    ((AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE))
        .set(
            AlarmManager.RTC,
            System.currentTimeMillis() + AlarmManager.INTERVAL_HOUR,
            PendingIntent.getService(
                getApplicationContext(),
                2,
                new Intent(this, SensorListener.class),
                PendingIntent.FLAG_UPDATE_CURRENT));

    WAIT_FOR_VALID_STEPS = true;

    return START_STICKY;
  }
 @Override
 public void onSensorChanged(final SensorEvent event) {
   steps = (int) event.values[0];
   if (WAIT_FOR_VALID_STEPS && steps > 0) {
     WAIT_FOR_VALID_STEPS = false;
     Database db = Database.getInstance(this);
     if (db.getSteps(Util.getToday()) == Integer.MIN_VALUE) {
       int pauseDifference =
           steps
               - getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS)
                   .getInt("pauseCount", steps);
       db.insertNewDay(Util.getToday(), steps - pauseDifference);
       if (pauseDifference > 0) {
         // update pauseCount for the new day
         getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS)
             .edit()
             .putInt("pauseCount", steps)
             .commit();
       }
       reRegisterSensor();
     }
     db.saveCurrentSteps(steps);
     db.close();
     updateNotificationState();
     startService(new Intent(this, WidgetUpdateService.class));
   }
 }
  @Override
  public void onReceive(final Context context, final Intent intent) {
    if (Logger.LOG) Logger.log("shutting down");

    // sensor stores steps since boot, so this value will be reset upon the
    // next boot and therefore has to be saved now
    Database db = new Database(context);
    db.open();
    db.updateSteps(Util.getToday(), SensorListener.steps);
    db.close();
    if (Logger.LOG) Logger.log("last step value before shutdown: " + SensorListener.steps);

    // if the user used a root script for shutdown, the DEVICE_SHUTDOWN
    // broadcast might not be send. Therefore, the app will check this
    // setting on the next boot and displays an error message if it's not
    // set to true
    context
        .getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS)
        .edit()
        .putBoolean("correctShutdown", true)
        .commit();
  }