75

I have a alarm thing going on in my app and it launches a notification that then when pressed launched an activity. The problem is that when I create more than one alarm then the activity launched from the notification gets the same extras as the first one. I think the problem is either with the intent i put in the pending intent or in the pending intent itself. I think I might need to put a flag on one of these but I dont know which one.

Intent showIntent =new Intent(context, notificationreceiver.class);
    showIntent.putExtra("details", alarmname);

PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
        showIntent, 0); 

    notification.setLatestEventInfo(context, "The event is imminent",
            alarmname, contentIntent);

And the receiver of the notification

Bundle b = getIntent().getExtras();
    String eventname = b.getString("details");
    details.setText(eventname);

The "details" extra is the same to every the next time a notification happens instead of having the different value. Until I set the intents I am sure that the correct value goes to the "details" so its a problem of getting the first intent everytime i press any notification. How can I make it to launch the correct intents? Hope I was as clear as i could Thanks!

spagi
  • 1,457
  • 4
  • 16
  • 19
  • What I did is since I am using a unique notificationId to keep track of the statuses (status bar notification), i use the same variable to pass into my PendingIntent thus making it unique. –  Aug 16 '11 at 22:11

5 Answers5

122

The way I solved that problem was by assigning a unique requestCode when you get the PendingIntent:

PendingIntent.getActivity(context, requestCode, showIntent, 0); 

By doing so you are registering with the system different/unique intent instances. Tip: A good way of making the requestCode unique would be by passing to it the current system time.

int requestID = (int) System.currentTimeMillis();
Bibaswann Bandyopadhyay
  • 3,389
  • 2
  • 31
  • 30
u-ramos
  • 1,221
  • 1
  • 8
  • 5
  • 9
    requestCode is indeed not used by anything as of yet, but it does make the intents unique which stops them being overwritten! Excellent work u-ramos! – Kitteh Jan 17 '12 at 11:55
  • 1
    Even if `TaskStackBuilder` is being used, we have a method there `getPendingIntent(int requestCode, int flags)` .Here this requestID can be passed to. – Abdullah Shoaib Nov 11 '13 at 07:20
  • 3
    Be careful, currentTimeMillis is type long, so if you cast to int, it will be truncated. I don't know how probable is and if it matters, but it could be repeated. In that case you can use a static incremented value – djpeinado Feb 06 '14 at 13:36
  • Great solution. Today I came to know what requestCode is for – Bibaswann Bandyopadhyay Oct 13 '15 at 06:43
  • Thank you! Perfect solution! – ruclip Feb 05 '16 at 11:10
  • What if you want later to cancel the `PendingIntent`? You should store the requestCode for each `PendingIntent`? – Fivos Mar 20 '19 at 11:29
70

The problem is that when I create more than one alarm then the activity launched from the notification gets the same extras as the first one.

Correct.

How can I make it to launch the correct intents?

That depends on whether you have two alarms that will be registered at once, or not.

If not, you can use FLAG_ONE_SHOT or one of the other PendingIntent flags to have your second PendingIntent use the newer extras.

If, however, you will have two alarms registered at once, with different Intent extras, you will need to make the two Intents be more materially different, such that filterEquals() returns false when comparing the two. For example, you could call setData() or setAction() and provide different values for each Intent.

Community
  • 1
  • 1
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 2
    Man thanks alot for the help. Because there is the possibility to have alarms going of together and having more than one notification on the notification bar I used the FLAG_UPDATE_CURRENT flag for the pending intent. But the real deal was as you said to setAction on the intent with the alarm name and now it could know which intents are different and what the same. Thanks again! – spagi Jun 10 '10 at 00:42
  • 2
    setAction worked for me too. I just wonder why the official SDK doesn't mention it. – Roman Royter Jan 23 '11 at 05:07
  • setAction works, thanks a TON. Using setAction helped me differentiate all the pendingIntents, just awesome! – Soham Nov 03 '11 at 06:54
  • using setAction to set different Action for each content Intent was key for me. Thanks a LOT! – Christian García Sep 19 '12 at 11:30
  • 2
    You can also use a different request code when creating pending intents, with a hash, that's quite convenient, and maybe cleaner than using setData – Snicolas Jul 25 '13 at 09:12
  • thanks alot :),i make app that give more than one notification at different time and make different action to each notification so faced this problem when put extra data but it solved just by using Intent intent1=new Intent(getBaseContext(),Splash.class); intent1.putExtra("iqama_ID",6);:PendingIntent contentIntent = PendingIntent.getActivity(getBaseContext(), notification_id, intent1, PendingIntent.FLAG_ONE_SHOT); – Amal Kronz Nov 13 '15 at 07:51
  • @CommonsWare I have set up my pendingIntents with unique requestCodes, using an int counter. I am trying to cancel a pendingIntent in Activity A from Activity B here: https://stackoverflow.com/questions/61161676/android-cancel-alarm-and-pendingintent-in-different-activity Any ideas on how to fix? – AJW Apr 12 '20 at 01:33
1

I followed the solution provided by U-ramos and this worked for me

int requestID = (int) System.currentTimeMillis();

PendingIntent pendingIntent = PendingIntent.getActivity(this, requestID, showIntent, 0);
tuomastik
  • 4,559
  • 5
  • 36
  • 48
0

I had this issue in my app and just generated a random number to over come overriding notifications intent:

int random= new Random().nextInt();
PendingIntent resultPendingIntent =
      stackBuilder.getPendingIntent(
              random,
              PendingIntent.FLAG_UPDATE_CURRENT
      );
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
bsh
  • 19
  • 2
-1

another solution:

use the PendingIntent.FLAG_UPDATE_CURRENT like this:

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

this worked for me

Abeer Sul
  • 944
  • 9
  • 22