[SOLVED] Android SDK 33: How to cancel PendingIntents on the AlarmManager that were created using FLAG_UPDATE_CURRENT


This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under
CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

Issue

In our app users can setup reminders for different tasks. In the current version (built with SDK 30), the notifications are basically created the following way:

...
PendingIntent notification = PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
getAlarmManager().setExact(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent);

Now Google forces us to upgrade to SDK 33, which is what we did. Unfortunately, after upgrading we were facing the following error when calling the method above:

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

The solution seemed to be quite simple: we just had to change the flag from FLAG_UPDATE_CURRENT to FLAG_IMMUTABLE to fix the error. But now the real problem showed up: By adjusting the PendingIntent I no longer have the possibility to delete the alarms of users who updated from a previous version. Here is why:

From my understanding, the only to way to delete an item from the alarm-manager is by using its cancel method. Unfortunately, the cancel method is asking me to pass the exact same PendingIntent that I used to create the Notification. E.g. to delete the notification from the example above, I would need to call:

PendingIntent notificationToDelete = PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
getAlarmManager().cancel(notificationToDelete);

Unfortunately, this leads back to the error we were facing in the beginning. But If I change the flag in the cancel method to FLAG_IMMUTABLE, the old notifications are not deleted, which totally makes sense because I am passing a different PendingIntent (I also tested it several times).

Of course, this is a very serious problem for us, because if users were to upgrade to the new version and delete their tasks, they would still get the notifications.

So now I’m at this very frustrating dead-end, wondering if I’m the only one affected by this problem. I’m not really an android expert, maybe I’m missing an obvious possibility. Does anyone know a way I can delete the “old” notifications from updating users by other means? Is there no way to just delete all current alerts without the need of recreating their intents first (e.g. using NotificationManager)? I am grateful for any hints!

Solution

Thanks to Saikrishna Rajaraman’s answer that helped us to find a solution for most of the users. Inspired by the snipped we wrote a function that deletes all “old” intents for all updating users, passing the “original” flags for all users where it’s still possible (SDK < 31):

int INTENT_FLAG = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT;
...
PendingIntent notificationToDelete = PendingIntent.getBroadcast(context, notificationID, notificationIntent, INTENT_FLAG);
getAlarmManager().cancel(notificationToDelete);

Unfortunately it only works for users with SDK < 31 since for Android 12 and 13 the intent does not match again and causes the original error.

Answered By – Christoph Göttert

people found this article helpful. What about you?