tomohiko sato
tomohiko sato

Reputation: 33

When deleting alarm from AlarmManager, should I also cancel PendingIntent?

I'm trying to delete alarm from AlarmManager. I just called AlarmManager.cancel(), and It seems to work fine. Should I also cancel PendingIntent and why?

PendingIntent p; // prepare a pending intent which matches target alarm's intent.
alarmManager.cancel(p);
p.cancel() // should I do that? 

Upvotes: 3

Views: 340

Answers (2)

ctate
ctate

Reputation: 1409

Never use FLAG_CANCEL_CURRENT with PendingIntents that you use when setting alarms. If you want to reschedule the alarm for a different time you don't need any flag at all; just create a duplicate PendingIntent with flags of zero and then use it to set() an alarm: this will implicitly cancel the existing alarm and then set it for the newly-specified time. If you used FLAG_CANCEL_CURRENT when you created the new PendingIntent, though, it breaks the Alarm Manager's ability to recognize that it's "the same" as the now-canceled PendingIntent, and you wind up with the old one hanging around, undeliverable, taking up memory and CPU. I've seen apps with this bug rack up literally hundreds of stale alarms in the system, enough to be a noticeable performance and memory-usage hit.

If you just want to change the extras without actually rescheduling the existing alarm, that is what FLAG_UPDATE_CURRENT is for. If you want to reschedule or cancel an existing alarm, don't use any flags at all.

Upvotes: 1

apelsoczi
apelsoczi

Reputation: 1123

It is not necessary to do this. But it matters upon your usage.

A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.

If you only need one PendingIntent active at a time for any of the Intents you will use, then you can alternatively use the flags FLAG_CANCEL_CURRENT or FLAG_UPDATE_CURRENT to either cancel or modify whatever current PendingIntent is associated with the Intent you are supplying.

Upvotes: 0

Related Questions