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!
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.
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.
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.