2017-04-12 78 views
0

我正在开发计步器。我有一个运行良好的服务。我也使我的服务前景。但是,如何使用传感器数据更新我的通知。我正在从传感器获取步骤。我只想在显示前台服务的通知中显示它。用传感器数据更新前台服务通知

 public class StepCounterService extends Service { 
    private static final String LOG_TAG = "ForegroundService"; 

    public static Boolean FLAG = false; 

    private SensorManager mSensorManager; 
    private StepDetector detector; 

    private PowerManager mPowerManager; 
    private WakeLock mWakeLock; 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     startServiceForeground(intent, flags, startId); 
     Log.d("zzz", "start command"); 

     return START_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     // TODO Auto-generated method stub 
     super.onCreate(); 
     new StepCountManager(this); 

     FLAG = true; 

     Log.e("Service_Started", ""); 
     detector = new StepDetector(this); 


     mSensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE); 

     mSensorManager.registerListener(detector, 
       mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
       SensorManager.SENSOR_DELAY_NORMAL); 


     mPowerManager = (PowerManager) this 
       .getSystemService(Context.POWER_SERVICE); 
     mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK 
       | PowerManager.ACQUIRE_CAUSES_WAKEUP, "S"); 
     mWakeLock.acquire(); 
     reloadSettings(); 
    } 

    @Override 
    public void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
     FLAG = false; 
     if (detector != null) { 
      mSensorManager.unregisterListener(detector); 
     } 

     if (mWakeLock != null) { 
      mWakeLock.release(); 
     } 

     Log.e("Service_destroyed", ""); 
    } 

    public void reloadSettings() { 

     if (detector != null) { 
      detector.setSensitivity(
        Float.valueOf("10") 
      ); 
     } 


    } 

    @Override 
    public void onTaskRemoved(Intent rootIntent) { 
     super.onTaskRemoved(rootIntent); 
     Intent restartService = new Intent(getApplicationContext(), 
       this.getClass()); 
     restartService.setPackage(getPackageName()); 
     PendingIntent restartServicePI = PendingIntent.getService(
       getApplicationContext(), 1, restartService, 
       PendingIntent.FLAG_ONE_SHOT); 

     //Restart the service once it has been killed android 


     ((AlarmManager) getSystemService(Context.ALARM_SERVICE)) 
       .set(AlarmManager.RTC, System.currentTimeMillis() + 1000, PendingIntent 
         .getService(this, 3, new Intent(this, StepCounterService.class), 0)); 


    } 

    public int startServiceForeground(Intent intent, int flags, int startId) { 

     Intent notificationIntent = new Intent(this, HomeActivity.class); 
     notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

     Notification notification = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.mipmap.ic_launcher) 
       .setContentTitle("Mobiefit Walk") 
       .setContentIntent(pendingIntent) 
       .setOngoing(true) 
       .build(); 
     NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     mNotificationManager.notify(300, notification); 
     Notification n; 

     startForeground(300, notification); 

     return START_STICKY; 
    } 


} 

我只是想显示我从传感器得到这个通知下的步骤。

这里是我step_detector类:

public class StepDetector implements SensorEventListener { 


    public static UpdateStepCount mStepsUpdater; 


    public static int CURRENT_SETP = 0; 

    public static float SENSITIVITY = 0; //SENSITIVITY 

    private float mLastValues[] = new float[3 * 2]; 
    private float mScale[] = new float[2]; 
    private float mYOffset; 
    private static long end = 0; 
    private static long start = 0; 
    private float mLimit = 10; 


    private float mLastDirections[] = new float[3 * 2]; 
    private float mLastExtremes[][] = { new float[3 * 2], new float[3 * 2] }; 
    private float mLastDiff[] = new float[3 * 2]; 
    private int mLastMatch = -1; 


    public StepDetector(Context context) { 
     // TODO Auto-generated constructor stub 
     super(); 
     int h = 480; 
     mYOffset = h * 0.5f; 
     mScale[0] = -(h * 0.5f * (1.0f/(SensorManager.STANDARD_GRAVITY * 2))); 
     mScale[1] = -(h * 0.5f * (1.0f/(SensorManager.MAGNETIC_FIELD_EARTH_MAX))); 

    } 
    public void setSensitivity(float sensitivity) { 
     mLimit = sensitivity; // 1.97 2.96 4.44 6.66 10.00 15.00 22.50 33.75 50.62 
    } 


    @Override 
    public void onSensorChanged(SensorEvent event) { 
     Log.d("AAA", "Sensor changed"); 




     Sensor sensor = event.sensor; 
     // Log.i(Constant.STEP_DETECTOR, "onSensorChanged"); 
     synchronized (this) { 
      if (sensor.getType() == Sensor.TYPE_ORIENTATION) { 
      } else { 
       int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0; 
       if (j == 1) { 
        float vSum = 0; 
        for (int i = 0; i < 3; i++) { 
         final float v = mYOffset + event.values[i] * mScale[j]; 
         vSum += v; 
        } 
        int k = 0; 
        float v = vSum/3; 

        float direction = (v > mLastValues[k] ? 1: (v < mLastValues[k] ? -1 : 0)); 
        if (direction == -mLastDirections[k]) { 
         // Direction changed 
         int extType = (direction > 0 ? 0 : 1); // minimum or 
         // maximum? 
         mLastExtremes[extType][k] = mLastValues[k]; 
         float diff = Math.abs(mLastExtremes[extType][k]- mLastExtremes[1 - extType][k]); 

         if (diff > mLimit) { 
          boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2/3); 
          boolean isPreviousLargeEnough = mLastDiff[k] > (diff/3); 
          boolean isNotContra = (mLastMatch != 1 - extType); 

          if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) { 
           end = System.currentTimeMillis(); 
           if (end - start > 500) { 
            Log.i("Step_Detector", "CURRENT_SETP:" 
              + CURRENT_SETP); 
            CURRENT_SETP++; 
            mLastMatch = extType; 
            start = end; 
           } 
          } else { 
           mLastMatch = -1; 
          } 
         } 
         mLastDiff[k] = diff; 
        } 
        mLastDirections[k] = direction; 
        mLastValues[k] = v; 
       } 
      } 
     } 
     Log.d("sensorSteps", String.valueOf(CURRENT_SETP)); 
     if(mStepsUpdater!=null){ 
      mStepsUpdater.UpdateStepCount(CURRENT_SETP); 
     } 



    } 




    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
     // TODO Auto-generated method stub 
    } 

    public static void callBackInit(StepCountManager stepCountManager) { 
     mStepsUpdater= stepCountManager; 
    } 
} 
+0

您需要将您的服务与正在进行的通知相关联,这样您的服务将始终运行。但是你仍然需要管理'Force Stop'场景。 –

回答

1

如果你想保持你的服务中运行,即使应用程序被杀害,请务必在onStartCommand()返回START_STICKY如下:

@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // 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)); 
return START_STICKY; 
    } 
+0

我已经将它添加到我的代码中。 –

+0

你已经提到START_NOT_STICKY在你的代码 –

0

你需要启动前台服务。 这是我的音乐播放器前台服务代码。

public class ForegroundService extends Service { 
private static final String LOG_TAG = "ForegroundService"; 
String audioPath; 
boolean audioPlayed = false; 
MediaPlayer mp; 
Thread backgroundThread; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    mp = MediaPlayer.create(this,R.raw.shapeofyou); 
    mp.setLooping(true); 

    backgroundThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      playMusic(); 
     } 
    }); 

} 

private void playMusic() { 
    mp.start(); 
    audioPlayed = true; 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
//  audioPath = intent.getStringExtra("path"); 
     if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) { 
      if (mp.isPlaying()){ 
       Toast.makeText(this,"Already playing",Toast.LENGTH_SHORT).show(); 
      } else { 
       backgroundThread.start(); 
      } 
      Log.i(LOG_TAG, "Received Start Foreground Intent "); 
      Intent notificationIntent = new Intent(this, MainActivity.class); 
      notificationIntent.setAction(Constants.ACTION.MAIN_ACTION); 
      notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
        | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
      PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 
        notificationIntent, 0); 

      Intent previousIntent = new Intent(this, ForegroundService.class); 
      previousIntent.setAction(Constants.ACTION.PREV_ACTION); 
      PendingIntent ppreviousIntent = PendingIntent.getService(this, 0, 
        previousIntent, 0); 

      Intent playIntent = new Intent(this, ForegroundService.class); 
      playIntent.setAction(Constants.ACTION.PLAY_ACTION); 
      PendingIntent pplayIntent = PendingIntent.getService(this, 0, 
        playIntent, 0); 

      Intent nextIntent = new Intent(this, ForegroundService.class); 
      nextIntent.setAction(Constants.ACTION.NEXT_ACTION); 
      PendingIntent pnextIntent = PendingIntent.getService(this, 0, 
        nextIntent, 0); 

      Bitmap icon = BitmapFactory.decodeResource(getResources(), 
        R.mipmap.ic_launcher); 

      Notification notification = new NotificationCompat.Builder(this) 
        .setContentTitle("Music Player") 
        .setTicker("Music Player") 
        .setContentText("My Music") 
        .setSmallIcon(R.mipmap.ic_launcher) 
        .setLargeIcon(
          Bitmap.createScaledBitmap(icon, 128, 128, false)) 
        .setContentIntent(pendingIntent) 
        .setOngoing(true) 
        .addAction(android.R.drawable.ic_menu_close_clear_cancel, 
          "Stop", ppreviousIntent) 
        .addAction(android.R.drawable.ic_media_play, "Play", 
          pplayIntent).build(); 
      startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, 
        notification); 
     } else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) { 
      stopForeground(true); 
      stopSelf(); 
      if (mp.isPlaying()) { 
       mp.release(); 
      } 
      backgroundThread = null; 
      Log.i(LOG_TAG, "Clicked Previous"); 
     } else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) { 
      if (audioPlayed) { 
       mp.pause(); 
       audioPlayed = false; 
      } else { 
       mp.start(); 
       audioPlayed = true; 
      } 
      Log.i(LOG_TAG, "Clicked Play"); 
     } else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) { 
      Log.i(LOG_TAG, "Clicked Next"); 
     } else if (intent.getAction().equals(
       Constants.ACTION.STOPFOREGROUND_ACTION)) { 
      Log.i(LOG_TAG, "Received Stop Foreground Intent"); 
      stopForeground(true); 
      stopSelf(); 
      if (mp.isPlaying()) { 
       mp.release(); 
      } 
      backgroundThread = null; 
     } 

    return START_STICKY; 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    Log.i(LOG_TAG, "In onDestroy"); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    // Used only in case of bound services. 
    return null; 
} 
} 
0
return START_STICKY; 

,当它被杀害,如低内存某些原因自动重新启动该服务。

+0

我添加,但它不起作用。 –

+0

你可以尝试使用前台通知。 [this](http://stackoverflow.com/a/11690802/6904440)可能会帮助你。 – Simo