16

My app sets a repeating alarm on user interaction, it might change the interval time set for the broadcast with Alarm Manager.
There is not much in the way of extras.
Is the update or cancel flag better in this case?

Thanks

Dory
  • 7,462
  • 7
  • 33
  • 55
  • What does 'There is not much in the way of extras' mean? Are you using extras or not? – Nikolay Elenkov Dec 26 '12 at 04:13
  • no i am not using extras.. – Dory Dec 26 '12 at 06:02
  • Be ware that Samsung Lollipop has issue when one is using FLAG_CANCEL_CURRENT. Refers to http://stackoverflow.com/questions/29344971/java-lang-securityexception-too-many-alarms-500-registered-from-pid-10790-u – Elye Jan 28 '16 at 01:20

2 Answers2

27

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, don't use any flags at all.

ctate
  • 1,379
  • 10
  • 11
  • Your answer sound opposite of what the Android documentation status about `FLAG_CANCEL_CURRENT`. Do you have any references for this answer? I am currently running into a problem where I suspect that the `FLAG_UPDATE_CURRENT` is not updating the intent extra properly due to which I end up with some unexpected behaviour. I want to change it to use `FLAG_CANCEL_CURRENT` and that's when I saw this answer. – Varun Gupta May 20 '18 at 04:24
  • What are you reading that sounds contradictory? d.android.com says that FLAG_CANCEL_CURRENT "ensures that only entities given the new data will be able to launch it" -- the old PendingIntent is invalid, only the new one will work, and .equals() on the two returns false. If you have issues with FLAG_UPDATE_CURRENT not changing the extras, that's a separate semantic. – ctate May 22 '18 at 01:18
  • 1
    I found your comment about the setting the flags to 0 contradictory. You have written that if the flags are set to 0, then `PendingIntent` will be canceled implicitly but if the flags are set to `FLAG_CANCEL_CURRENT`, then the old one will be hanging around undeliverable. I wrote a small test where I created two PendingIntents with same `requestCode`. When I set the flags to 0, the previous `PendingIntent` was still valid when I invoked `send` on it. When I set the flags to `FLAG_CANCEL_CURRENT`, then the previous intent was canceled and I was not able to send it. – Varun Gupta May 22 '18 at 03:09
  • I'm sorry; I don't quite follow. I wrote "this will implicitly cancel the existing alarm" -- it cancels the *alarm,* not the PendingIntent. What you describe seeing -- that after using FLAG_CANCEL_CURRENT the previous PendingIntent instance is no longer usable -- is exactly why I'm saying you must not use that flag with PendingIntents that are associated with alarms. – ctate May 23 '18 at 21:32
15

If you are not using extras, you don't have to specify any of those flags. They only change how the systems handles extras with a PendingIntent: replace the ones in the current matching (cached by the system PendingIntent) or cancel it and create a new one. Refer to the documentation for details: http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_CANCEL_CURRENT

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84