Env: - Android 6.0, Huawei Smartphone
My app is an IM client which must keep connection with a server and receives message from it. So i have to keep it alive all the time, as long as the network connection is available.
I used the foreground servie to keep my app alive in background. See: android-keeping-a-background-service-alive-preventing-process-death This method works fine on Android 4.1 and 4.4. But it fails on Android 5.1 and 6.0. The app process is killed about 10 seconds after clicking POWER button.
Below is the re-produce steps. It is a simple demo app, which starts a thread to track whether the process is killed or alive.
- Start an android app with an activity;
- Start a logging thread to log a message every second;
Override service onStartCommand() method, call startForeground() and to show a notificaiton;
click a button to start a service;
- Press HOME/BACK button on smart phone to return to home page;
- Press POWER button to shut down the screen;
Wait about 10 seconds, logging thread stops;
click the app icon to start the app, again;
- logging thread starts, but its index begins from 0; And PID has changed (See screen shot below)!
NOTE: I notice a strange thing: When the app starts again, onCreate() of the activity is NOT called!
Any help is appreciated! Thanks in advance!
Here is my code to start service:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
AppGlobal.logDebug(">>>> onStartCommand()");
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "==== Received Start Foreground Intent ");
showNotification();
Toast.makeText(this, "Service Started!", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
Log.i(LOG_TAG, "Clicked Previous");
Toast.makeText(this, "Clicked Previous!", Toast.LENGTH_SHORT)
.show();
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Log.i(LOG_TAG, "Clicked Play");
Toast.makeText(this, "Clicked Play!", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
Log.i(LOG_TAG, "Clicked Next");
Toast.makeText(this, "Clicked Next!", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(
Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "==== Received Stop Foreground Intent");
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
private void showNotification() {
AppGlobal.logDebug(">>>> show notification");
Intent notificationIntent = new Intent(this, StTest33MainActivity.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.drawable.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("TutorialsFace Music Player")
.setTicker("TutorialsFace Music Player")
.setContentText("My song")
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.addAction(android.R.drawable.ic_media_previous, "Previous",
ppreviousIntent)
.addAction(android.R.drawable.ic_media_play, "Play",
pplayIntent)
.addAction(android.R.drawable.ic_media_next, "Next",
pnextIntent).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
}