d.moncada
d.moncada

Reputation: 17402

How to cancel a foreground service from using the notification (swipe dismiss) or clear all notifications?

I'm currently creating a foreground service with a notification that appears in the notification bar when the service starts. If the service stops, the notification dismisses. My question is, is there a way to stop the service when "clear all notifications" or a dismiss of the notification (swipe) occurs?

Updated to include implementation of notification:

public int onStartCommand(Intent intent, int flags, int startId)
{   
    Log.d(CLASS, "onStartCommand service started.");

    if (getString(R.string.service_start_action) == intent.getAction())
    {
        Intent intentForeground = new Intent(this, ServiceMain.class)
            .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);    
        PendingIntent pendIntent = PendingIntent.getActivity(getApplicationContext(), 0, intentForeground, 0);      
        Notification notification;
        Notification.Builder builder = new Notification.Builder(getApplicationContext())
            .setSmallIcon(android.R.drawable.btn_star)
            .setTicker("Service started...")
            .setContentIntent(pendIntent)
            .setDefaults(Notification.DEFAULT_ALL)
            .setOnlyAlertOnce(true)
            .setOngoing(false);
        notification = builder.build();
        notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;

        startForeground(SERV_NOTIFY, notification);
        player.start();
    }
    else
    {
        Log.d(CLASS, "onStartCommand unable to identify acition.");
    }

    return START_STICKY;        
}

Upvotes: 30

Views: 32743

Answers (6)

abdo
abdo

Reputation: 1

I did the following and it worked for me:

  1. I created a notification before calling the foreground service with by same id and Notification Channel which are used with foreground service's notification

  2. I canceled the notification by the notification id

  3. I created another notification with your required structure

  4. You can dismiss or swipe this last notification without stop your foreground service

Upvotes: 0

Kevin Lee
Kevin Lee

Reputation: 2347

The user is not allowed to swipe away a notification generated by an ongoing foreground service.

Hence, stopForeground(false) first, which allows the notification to be swiped away by the user thereafter (at least on Lollipop+). For pre-Lollipop, you may have to stopForeground(true), which stops foreground and removes the notification, then re-issue the notification with notificationManager.notify(yourNotificationID, yourNotificationObject), so that your notification is visible but swipeable.

Crucially, set up the notification object with a delete intent that is triggered when the user swipes it away.

(new NotificationCompat.builder(this).setDeleteIntent(deletePendingIntent)).build()

where deletePendingIntent is something like

Intent deleteIntent = new Intent(this, YourService.class);
deleteIntent.putExtra(someKey, someIntValue);
PendingIntent deletePendingIntent = PendingIntent.getService(this,
someIntValue, 
deleteIntent, 
PendingIntent.FLAG_CANCEL_CURRENT);

When the user swipes it away, the intent with its extra is delivered to the service. Handle the delivered extra within onStartCommand, i.e. check that intent != null, intent.getExtras() != null, then extract the value from the extras bundle given someKey, and if it matches someIntValue, then call stopSelf().

Upvotes: 38

cmnewfan
cmnewfan

Reputation: 129

this code works for me:

this.stopForeground(false);
mNotificationManager.cancel(NOTIFY_ID);

and you should set your return value of onStartCommand, STRAT_STICKY will restart your service.

Upvotes: 8

CommonsWare
CommonsWare

Reputation: 1007534

My question is, is there a way to stop the service when "clear all notifications" or a dismiss of the notification (swipe) occurs?

Assuming that your Notification is set up to allow it to be cleared, the deleteIntent should be invoked when it is cleared. You could set this to a getBroadcast() PendingIntent, pointing to a manifest-registered BroadcastReceiver that calls stopService().

Upvotes: 5

Luis
Luis

Reputation: 12058

The notification of a foregraound service cannot be cleared. The only way is stopping the service.

So I beleive the issue you want to solve, will never happen.

Upvotes: 6

dnkoutso
dnkoutso

Reputation: 6061

There is a dismissIntent you can set in the notification you create, though I thought foreground Service notifications cannot be cleared?

Upvotes: 0

Related Questions