0

I'm developing an app that has to be active all the time, It's going to be used on a device that will be used exclusively for the app.

I've read that to not let the app be killed by the OS I need to set an ongoing notification, I also applied a partial wakelock.

The problem is the notification doesn't go away if the app is killed, I call this on the onCreate method of my activity

notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(getApplicationContext(), PlayerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 8000, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification.Builder builder = new Notification.Builder(getApplicationContext())
        .setContentTitle("Title")
        .setContentText("Description")
        .setContentIntent(pendingIntent)
        .setSmallIcon(R.mipmap.ic_playlist_play_white_36dp)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.app_icon))
        .setOngoing(true);

notificationManager.notify(8000, builder.build());

on the onDestroy method I call

notificationManager.cancelAll();
super.onDestroy();

The notification never gets removed, I have to uninstall the app for it to be killed, is there a way to remove it when the app is not loaded?

Edit: I'm targeting API 19

Roberto Arosemena
  • 1,140
  • 1
  • 9
  • 18
  • Unfortunately onDestroy method is not a safe place for doing this and Android may not call this method in some situations. May be you have to create a Service for handling this situation, if it is necessary! – Mohsen Mirhoseini Oct 10 '16 at 17:01

1 Answers1

1

You should be using a Foreground Service, which will prevent the OS from killing your app (setting a notification as ongoing alone will not prevent that). Services also provide a means to detect the app being swiped away via onTaskRemoved().

First you need to declare the service in your manifest:

<service android:name="com.your.app.NotificationService"/>

Then start the Service from an Activity:

Intent intent = new Intent(this, NotificationService.class);
intent.putExtra("key", "value"); // if you have extras
this.startService(intent);

Set the Service as a Foreground Service in onStartCommand():

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Intent pending = new Intent(getApplicationContext(), PlayerActivity.class);
    pending.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 8000, pending, PendingIntent.FLAG_CANCEL_CURRENT);
    Notification.Builder builder = new Notification.Builder(getApplicationContext())
            .setContentTitle("Title")
            .setContentText("Description")
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.mipmap.ic_playlist_play_white_36dp)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.app_icon))
            .setOngoing(true);

    startForeground(8000, builder.build());

    return (START_NOT_STICKY);
}

Finally handle onTaskRemoved() and onDestroy():

@Override
public void onTaskRemoved(Intent rootIntent) {
    stopSelf();
}

@Override
public void onDestroy() {
    stopForeground(true); // 'true' removes notification too
}

N.B. Calling stopSelf() will destroy the Service, and then stopForeground() will remove the notification automatically.

Finally, if you wish to manually stop the Service from an Activity, you can simply do this:

Intent intent = new Intent(this, NotificationService.class);
this.stopService(intent);
Mr. Kevin Thomas
  • 837
  • 2
  • 13
  • 21
  • This is what i needed; Is the partial wakelock not enough to keep the activity alive?, the main objective of the app is to play audio files from remote http servers, just need to keep it alive forever while the screen is off – Roberto Arosemena Oct 11 '16 at 18:03
  • 1
    see: http://stackoverflow.com/questions/9104622/android-foreground-service-vs-wakelock ... the partial wakelock ensure the CPU is awake to execute your tasks, and the foreground service ensures your app is prioritized to not be killed on low memory – Mr. Kevin Thomas Oct 11 '16 at 19:01