Reputation: 85
I am developing a pedometer. I have a service which is running fine. I made my service foreground also. But how do I update my notification with sensor data. I am getting steps from sensor. I just want to show it in a notification which is showing usig the foreground service.
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;
}
}
I just want to show my steps under this notification which I am getting from sensor.
Here is my step_detector class:
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;
}
}
Upvotes: 2
Views: 2160
Reputation: 345
return START_STICKY;
to automatically restart the service when it gets killed for some reasons like low memory.
Upvotes: 0
Reputation: 1376
You need to start a Foreground Service. This is my music player Foreground service code.
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;
}
}
Upvotes: 0
Reputation: 1396
If you want to keep your service running even if the app is killed, make sure to return START_STICKY in onStartCommand()
as follows :
@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;
}
Upvotes: 1