10

I'm using below snippet to show a notification from a service inside my app:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle(currentNotificaion.getMessageTitle())
                .setContentIntent(contentIntent)
                .setContentText(currentNotificaion.getMessageText())
                .setAutoCancel(true);
int mNotificationId = (int) currentNotificaion.getMessageServerID();
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());

My service is declared like this in manifest:

<service
android:name="com.myapp.services.NotificationService"
android:stopWithTask="false">
</service>

But when closing my app from recent apps list, notification is disappear and removed from notification bar. Another things is I'm not going to use stick notifications which are never removed from notification bar.

How can I avoid this?

VSB
  • 9,825
  • 16
  • 72
  • 145

5 Answers5

6

Inside your Manifest file, keep flag stopWithTask as true for Service. Like:

<service
    android:name="com.myapp.MyService"
    android:stopWithTask="true" />

I just resolved a similar kind of issue.

Here is what you can do if its just about stopping service when application is killed by swiping from Recent app list.

  1. Inside your Manifest file, keep flag stopWithTask as true for Service. Like:

But as you say you want to unregister listeners and stop notification etc, I would suggest this approach:

Inside your Manifest file, keep flag stopWithTask as false for Service. Like:

    <service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />
  1. Now in your MyService service, override method onTaskRemoved. (This will be fired only if stopWithTask is set to false).

    public void onTaskRemoved(Intent rootIntent) {
    
    //unregister listeners
    //do any other cleanup if required
    
    //stop service
        stopSelf();  
    }
    

Hope it will help you.

Jamil Hasnine Tamim
  • 4,389
  • 27
  • 43
  • I have applied same but still after clear notification remove from notification manager – MARSH May 28 '22 at 02:22
  • @MARSH what is your requirement? – Jamil Hasnine Tamim May 28 '22 at 17:24
  • Thanks for response , I want uncancellable or uclear notification it should hide and show from app only i have posted my question here also please help me in this https://stackoverflow.com/questions/72372057/how-to-unclear-and-uncancellable-notification-from-notification-bar – MARSH May 28 '22 at 18:26
4

If you want a background service running with a foreground notification, the best way is to use startForeground() function. You can check Android docs here and there are some answers about it in SO also like this from @CommonsWare with example included.

Hope it helps!

Community
  • 1
  • 1
Hugo
  • 1,662
  • 18
  • 35
  • It doesn't help if the user kills the app – Vyacheslav Nov 02 '16 at 11:27
  • It does, but for that you have to use `return START_STICKY;` as return in the `onStartCommand(...)` within the service. It will mantain service running even when killing the app from recent apps ;) – Hugo Nov 02 '16 at 11:54
2

If you want to show your notification after your application is killed I would suggest this.

As wrote @JamilHasnineTamim you can catch the event when the application is killed from the device.

<service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />

inside service

public void onTaskRemoved(Intent rootIntent) {
//your code
//stop service
    stopSelf();  
}

but, inside this code you can charge an AlarmManager to restart your own notification after a few seconds. Put this inside onTaskRemoved:

AlarmManager am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
Intent intent = new Intent(BRNotificator.INTENT_FILTER);
int somealarmnumber = 10000;//or any numbe your want
long nexttime = System.currentTimeInMillis() + 5000L;
PendingIntent pi =PendingIntent.getBroadcast(ctx, somealarmnumber, intent, PendingIntent.FLAG_CANCEL_CURRENT):
am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pi);

where broadcast reciever is:

public class BRNotificator extends WakefulBroadcastReceiver {
    public static final String INTENT_FILTER = "com.example.BRNotificator";
    @Override
    public void onReceive(Context ctx, Intent intent) {
//restart your service this notification
        OWakeLocker.acquire(ctx, 0);
        ComponentName comp = new ComponentName(ctx.getPackageName(),
                YourServiceClass.class.getName());
        startWakefulService(ctx, intent.setComponent(comp));

//or just show your notification again:
NotificationCompat.Builder mBuilder = //... your code to show
    }

}

this is a helper that can help to wake up your device :

public class OWakeLocker {
    private static PowerManager.WakeLock[] wakeLocks = new PowerManager.WakeLock[1];//Services count

    @SuppressWarnings("deprecation")
    public static void acquire(Context ctx, int index) {
        WakeLock wakeLock = wakeLocks[index];
        if (wakeLock != null) wakeLock.release();

        PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
                    PowerManager.ACQUIRE_CAUSES_WAKEUP |
                    PowerManager.ON_AFTER_RELEASE, _.APPNAME + Integer.toString(index));
        if (wakeLock != null && wakeLock.isHeld()){
            wakeLock.acquire();
        }
    }

    public static void release(int index) {
        WakeLock wakeLock = wakeLocks[index];
        if (wakeLock != null) 
            wakeLock.release();
            wakeLock = null;
    }
}
Community
  • 1
  • 1
Vyacheslav
  • 26,359
  • 19
  • 112
  • 194
0

You can even

public static void clearNotifications(Context context) {
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.cancelAll();
}
Roma Darvish
  • 257
  • 5
  • 19
-1
 .setAutoCancel(true);

Let's set this to false, so notification is not canceled and not removed. You can also put

.setOngoing(true)

Update: If above does not work and when notification is send from service, you need to call

 startForeground(int, Notification) 

in order to do not kill service when app gets killed.

From Android documentation:

A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.

More could be found here: Android Service startForeground

Rafal
  • 292
  • 2
  • 10
  • 1
    if I do `.setAutoCancel(true);` it will not be removed by clicking on notification. `.setOngoing(true)` also display notification forever. I want notification will removed by touching them however not removed by removing app from recent apps list. – VSB Oct 26 '16 at 11:19
  • 2
    Ok. How do you starting your service ? maybe startForeground will help. – Rafal Oct 26 '16 at 11:28
  • Please post your comment as an answer or update this answer so I can accept it as true answer. `startForeground` helped me to resolve my problem. – VSB Nov 02 '16 at 11:08