8

From the documentation of Pending Intent FLAG_CANCEL_CURRENT in Android:

by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT

Can anyone explain what this line means?

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
pikini
  • 175
  • 2
  • 14

1 Answers1

23

Once you create a new PendingIntent with FLAG_CANCEL_CURRENT, anything holding a previous PendingIntent for the same Intent will no longer be able to execute that original PendingIntent.

For example, suppose we have this:

Intent i=new Intent(this, Foo.class);

i.putExtra("key", 1);

PendingIntent pi=PendingIntent.getActivity(this, 0, i, 0);

and we use that PendingIntent with, say, a Notification.

Later on, we execute:

Intent i=new Intent(this, Foo.class);

i.putExtra("key", 2);

PendingIntent pi2=PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);

At this point, the PendingIntent created originally (pi) is no longer valid, and whatever we use pi2 for will see the updated extra value (2).

If, instead, we did:

Intent i=new Intent(this, Foo.class);

i.putExtra("key", 2);

PendingIntent pi2=PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

At this point, pi and pi2 both represent the same PendingIntent, and both will see the updated extra value (2).

Or, if we did:

Intent i=new Intent(this, Foo.class);

i.putExtra("key", 2);

PendingIntent pi2=PendingIntent.getActivity(this, 0, i, 0);

At this point, pi and pi2 still represent the same PendingIntent, but the extras are unchanged, as getActivity() returns the original PendingIntent without applying the new extras.

Most times, FLAG_UPDATE_CURRENT is a fine answer when you are trying to replace extras inside a PendingIntent.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Intent i=new Intent(this, Foo.class); i.putExtra("key", 1); PendingIntent pi=PendingIntent.getActivity(this, 0, i, 0); AlarmManager am = Context.getSystemService(Context.ALARM_SERVICE); am.set(ELAPSED_REALTIME,mTime,pi); Intent i=new Intent(this, Foo.class); i.putExtra("key", 2); PendingIntent pi2=PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_CANCEL_CURRENT); am.set(ELAPSED_REALTIME,mTime1,pi2); So, now when alarm manager expires at time mTime, the pending intent pi won't be called ? – pikini Feb 24 '13 at 14:38
  • 2
    @pikini: I would expect that `PendingIntent.CanceledException` would be thrown. Presumably, `AlarmManager` has logic to deal with this. If you want to cancel an alarm, though, it is better to call `cancel()` rather than just letting `AlarmManager` deal with the exception, IMHO. – CommonsWare Feb 24 '13 at 14:40
  • Thanks for the answer. I will try out doing this and share my results. Thanks for your time to reply back. – pikini Feb 24 '13 at 14:51
  • PendingIntent.FLAG_UPDATE_CURRENT `At this point, pi and pi2 both represent the same PendingIntent, and both will see the updated extra value (2).` Suppose if they both are register with a alarm manager and when alarm time reaches will BOTH gets executed and what if PendingIntent.FLAG_CANCEL_CURRENT is used for above case? – Muhammad Babar Oct 27 '14 at 10:02
  • 2
    @MuhammadBabar: "Suppose if they both are register with a alarm manager and when alarm time reaches will BOTH gets executed" -- for truly equivalent `PendingIntent` objects, the second alarm would unschedule the first alarm. You cannot have two outstanding alarms for equivalent `PendingIntent` objects. – CommonsWare Oct 27 '14 at 10:37
  • What if i want to keep both trigger even then what should I use instead of FLAG_CANCEL_CURRENT – Lokesh Tiwari Mar 11 '16 at 19:49
  • @LokeshTiwari: They have to be different `PendingIntent` objects. Pass different `int` values as the second parameter to `getActivity()`, `getService()`, or `getBroadcast()`. – CommonsWare Mar 11 '16 at 19:57
  • If I set different Action on the Intent, would that be same or different Intent? – Mostafa Imran Oct 31 '16 at 12:05
  • @MostafaImran: Two `Intents` with different action strings are two different `Intents` -- they are not equivalent `Intents`. – CommonsWare Oct 31 '16 at 12:14
  • @CommonsWare how I can test it? I have created one pending Intent and add it with notification. then I use same intent with pending Intent and add FLAG_CANCEL_CURRENT but I didn't add this pendingIntent2 to notification and clicking on notification Intent didn't execute or open the activity as you mentioned in Intent(); here is the example link I use. https://pastebin.com/WKz8Ganc – Asif Mushtaq Aug 06 '17 at 19:18
  • @UnKnown: Please open separate questions when you have enough source code to warrant a pastebin. In your case, you cancelled the `PendingIntent` in the `Notification`, but you then threw away your new `PendingIntent`. Android does not go around and find all occurrences of the old `PendingIntent` and replace it with the new one. Either use `FLAG_UPDATE_CURRENT` or re-raise the `Notification` with the new `PendingIntent`. – CommonsWare Aug 06 '17 at 19:39
  • Can you give me link from where you read it? `Android does not go around and find all occurrences of the old PendingIntent and replace it with the new one.` – Asif Mushtaq Aug 07 '17 at 04:21
  • To anyone stumbling here because their Intents are not firing, they're most likely overriding one another. see [this](https://stackoverflow.com/a/45824534/2445763) and [this](https://stackoverflow.com/a/44688505/2445763) for adding uniqueness to your Intents. – lasec0203 Oct 28 '19 at 19:45