How to detect if a notification has been dismissed?
Asked Answered
H

3

29

Is there any way in Android to detect when a user swipes a notification to the left and deletes it? I'm using an alarmmanager to set a repeating alert and I need my repeating alert to stop when the notification is cancelled by the user. Here's my code:

Setting the repeating alert:

AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), repeatFrequency, displayIntent);

My notification code:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Get the notification ID.
    int notifID = getIntent().getExtras().getInt("Reminder_Primary_Key");

    //Get the name of the reminder.
    String reminderName = getIntent().getExtras().getString("Reminder_Name");

    //PendingIntent stores the Activity that should be launched when the user taps the notification.
    Intent i = new Intent(this, ViewLocalRemindersDetail.class);
    i.putExtra("NotifID", notifID);
    i.putExtra("notification_tap", true);

    //Add FLAG_ACTIVITY_NEW_TASK to stop the intent from being launched when the notification is triggered.
    PendingIntent displayIntent = PendingIntent.getActivity(this, notifID, i, Intent.FLAG_ACTIVITY_NEW_TASK);

    NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notif = new Notification(R.drawable.flag_red_large, reminderName, System.currentTimeMillis());

    CharSequence from = "Here's your reminder:";

    CharSequence message = reminderName;        
    notif.setLatestEventInfo(this, from, message, displayIntent);

    //Pause for 100ms, vibrate for 250ms, pause for 100ms, and vibrate for 500ms.
    notif.defaults |= Notification.DEFAULT_SOUND;
    notif.vibrate = new long[] { 100, 250, 100, 500 };
    nm.notify(notifID, notif);

    //Destroy the activity/notification.
    finish();

}

I know I need to call alarmManager.cancel(displayIntent) in order to cancel my repeating alarm. However, I don't understand where to put this code. I need to cancel the repeating alert ONLY when the user has tapped on the notification or dismissed it. Thanks for your help!

Hypochondriasis answered 30/9, 2012 at 21:7 Comment(1)
Never mind, I found my answer here: #8812376.Hypochondriasis
C
24

I believe that Notification.deleteIntent is what you are looking for. The doc says:

The intent to execute when the notification is explicitly dismissed by the user, either with the "Clear All" button or by swiping it away individually. This probably shouldn't be launching an activity since several of those will be sent at the same time.

Crouse answered 13/4, 2014 at 20:10 Comment(1)
Alternativ documentation: NotificationCompat.Builder#setDeleteIntent(PendingIntent)Donia
I
4

To all those future people out there -- you can register a broadcast receiver to listen for notification delete inents.

Create a new broadcast receiver:

public class NotificationBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (action == null || !action.equals(Config.NotificationDeleteAction)) {
            return;
        }

        // Do some sweet stuff
        int x = 1;
    }
}

Register the broadcast receiver within your application class:

"If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts (broadcasts that do not target your app specifically)."

Android Documentation.

  registerReceiver(
        new NotificationBroadcastReceiver(),
        new IntentFilter(Config.NotificationDeleteAction)
  );

You probably noticed the static variable Config.NotificationDeleteAction. This is a unique string identifier for your notification. It typically follows the following {namespace}{actionName} convention:

you.application.namespace.NOTIFICATION_DELETE

Set the delete intent on your notification builder:

notificationBuilder
       ...
        .setDeleteIntent(createDeleteIntent())
       ...

Where, createDeleteIntent is the following method:

private PendingIntent createDeleteIntent() {
    Intent intent = new Intent();
    intent.setAction(Config.NotificationDeleteAction);

    return PendingIntent.getBroadcast(
            context,
            0,
            intent,
            PendingIntent.FLAG_ONE_SHOT
    );
}

Your registered broadcast receiver should receive the intent when your notification is dismissed.

Insurgent answered 4/11, 2017 at 4:38 Comment(1)
Thanks for this. Incidentally, I have targetSdkVersion 30 and I was able to specify the BroadcastReceiver in the manifest only - with an <intent-filter /> that corresponds to Config.NotificationDeleteAction.Dongdonga
B
1

You can also use an Activity PendingIntent, which may be simpler to implement if you have an Activity that can handle the dismissal, because you don't have to create and configure a broadcast receiver.

public static final String DELETE_TAG = "DELETE_TAG";

private PendingIntent createDeleteIntent(Context context) {
    Intent intent = new Intent(context, MyActivity.class);
    intent.putExtra(DELETE_TAG, true);

    return PendingIntent.getActivity(
            context,
            0,
            intent,
            PendingIntent.FLAG_ONE_SHOT
    );
}

MyActivity would receive the intent in its onCreate(), and in this example, could look for the DELETE_TAG extra to recognize it.

Bedclothes answered 19/4, 2018 at 4:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.