0

Having quite a bit of trouble getting my foreground service to simply dismiss on swipe or by the clear all notifications button. I know there are several questions like this, but I have read them and will list some of what I've already tried. I tried this method, where you pass a simple intent with an extra into a pending intent, then add that pending intent to setDeleteIntent(). That didn't work, it never gets called.

I also tried this (second highest answer, "fully fleshed out" version), with the same results. Which ties in to the "answer" of this question as well. With how many apps have notifications that are dismissible with a swipe or clear all button, I must be missing something very obvious and I can't figure out what.

What my current code looks like (all of this inside of my service class).

BroadcastReceiver class

public class NotificationDismissedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // this is never called
        stopSelf();
    }
}

// in the manifest for that BroadcastReceiver, have also tried it with these values false
android:exported="true"
android:enabled="true"

Pending intent

private PendingIntent createOnDismissedIntent(Context context, int notificationId) {
    Intent intent = new Intent(context.getApplicationContext(), NotificationDismissedReceiver.class);

    PendingIntent pendingIntent =
            PendingIntent.getBroadcast(context.getApplicationContext(),
                    notificationId, intent, 0);
    return pendingIntent;
}

In the notification builder (101 is what I startForeground with)

.setDeleteIntent(createOnDismissedIntent(this, 101))

Edit:

Separate file receiver used instead of the inner class version.

public class NotificationDismissedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    int notificationId = intent.getExtras().getInt("notificationId");
    /* Your code to handle the event here */
    if(notificationId == 101){
        Intent stopIntent = new Intent(context, AssistorServiceClass.class);
        context.stopService(stopIntent);
    }
}
}

Edit2

To be clear, I'm not trying to stop the foreground notification and keep the service alive. I want them both just gone, as if I called stopSelf within the service class.

therealone
  • 421
  • 10
  • 22
  • It's not quite clear where you're at, currently. In the first approach, have you stopped the foreground status of the `Service` when you try to swipe the `Notification` away? Or do you mean that you just can't swipe it away at all? The second approach won't work, in either case, because `NotificationDismissedReceiver` is an inner class in your `Service`, and is therefore not able to be successfully registered in the manifest, nor broadcast to by an explicit `Intent`. – Mike M. Dec 13 '19 at 07:29
  • In the first approach and all approaches, yes, I can't swipe away at all. For the second approach, I have now created the broadcast receiver as a separate file and registered it in the manifest, still no luck. Where I'm currently at is the code in the post, I'll edit in what the new receiver looks like too. Put a breakpoint in the new receiver and it is not called when trying to swipe the notification/hitting clear all notifications. Having put breakpoints all over, I have not yet seen swiping to dismiss call anything. – therealone Dec 13 '19 at 08:11
  • "In the first approach and all approaches, yes, I can't swipe away at all." – OK, yeah, that's the first thing addressed in the top answer on your first link. You just can't swipe away a `Notification` for a `Service` in the foreground. And since you can't swipe, the delete `PendingIntent` will never fire. You would need to stop the foreground status of the `Service` first. – Mike M. Dec 13 '19 at 08:26
  • I did read that, and have had stopForeground(false) called. Sorry I forgot to mention that. What I was unclear about with that though, is that in his response he says "Hence, stopForeground(false) first," which I am unsure of where exactly that is meant to be called. I took it literally and have stopForeground called first thing in onCreate. – therealone Dec 13 '19 at 08:38
  • Also want to clarify, when I say that it doesn't swipe, on my phone it "swipes" a little bit and shows a gear icon to block notifications to my app. Idk if that's consequential, just some more information in case it's relevant. – therealone Dec 13 '19 at 08:43
  • Well, your `Service` is still foreground, though, if you can't swipe the `Notification`. You're likely calling `startForeground()` in `onStartCommand()`, which runs after `onCreate()`, so calling `stopForeground()` there doesn't really do anything. What this boils down to is that you can't really use the swipe and delete `PendingIntent` to stop a `Service`'s foreground status. That solution is only really useful for when you've already stopped the foreground status, and are leaving the `Notification` there for the user to stop the `Service` completely. – Mike M. Dec 13 '19 at 08:46
  • To stop the foreground status from the `Notification`, you'll have to use another mechanism, like a "Stop" button. – Mike M. Dec 13 '19 at 08:47
  • That's unfortunate, thanks. Out of curiosity how does something like Google Play's music foreground service differ from mine fundamentally? Seeing as they're both foreground media style notifications, but mine can't be dismissed with a swipe while theirs can. – therealone Dec 13 '19 at 08:53
  • That's a good question. I have no idea. AFAIK, regular apps are just stuck with this behavior. I wouldn't be surprised if Google is using some non-public API to accomplish that, or possibly they just have special allowance to run a `Service` without the ongoing, un-swipeable `Notification`, or maybe something else I'm not thinking of, atm. It is their OS, after all. I'll do a little digging around, here in a minute, and let you know if I find anything, but I'm thinking we just can't do it like that. I've been wrong before, though. :-) – Mike M. Dec 13 '19 at 09:01
  • Thank you for the help so far. I'll keep looking too. – therealone Dec 13 '19 at 09:06
  • I stop a foreground service by clicking on the notification. No buttons needed at all. At the moment no code at hand. – blackapps Dec 13 '19 at 14:06
  • I assume that's with autoCancel? Clicking on the notification is necessary for me to bring the user to the app. – therealone Dec 13 '19 at 23:03

0 Answers0