使用传感器数据更新前台服务通知

时间:2017-04-12 10:20:39

标签: android android-service android-sensors

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

     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;
    }
}

3 个答案:

答案 0 :(得分:1)

如果您希望即使应用程序被杀死也能保持服务正常运行,请确保在quantity = 1中返回START_STICKY,如下所示:

onStartCommand()

答案 1 :(得分: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;
}
}

答案 2 :(得分:0)

return START_STICKY;

由于内存不足等原因而被杀死时自动重启服务。