Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PendingIntent works correctly for the first notification but incorrectly for the rest

People also ask

Why would you use a PendingIntent?

Android PendingIntent In other words, PendingIntent lets us pass a future Intent to another application and allow that application to execute that Intent as if it had the same permissions as our application, whether or not our application is still around when the Intent is eventually invoked.

What is requestCode in PendingIntent?

1- requestCode is used to get the same pending intent later on (for cancelling etc) 2- Yes, they will get override as long as your specify the same Receiver to your Intent that you specify on your PendingIntent.


Don't use Intent.FLAG_ACTIVITY_NEW_TASK for PendingIntent.getActivity, use FLAG_ONE_SHOT instead


Copied from comments:

Then set some dummy action on the Intent, otherwise extras are dropped. For example

intent.setAction(Long.toString(System.currentTimeMillis()))

Was struggling with RemoteViews and several different Intents for each Button on HomeScreen Widget. Worked when added these:

1. intent.setAction(Long.toString(System.currentTimeMillis()));

2. PendingIntent.FLAG_UPDATE_CURRENT

        PackageManager pm = context.getPackageManager();

        Intent intent = new Intent(context, MyOwnActivity.class);
        intent.putExtra("foo_bar_extra_key", "foo_bar_extra_value");
        intent.setAction(Long.toString(System.currentTimeMillis()));
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.widget_layout);
        views.setOnClickPendingIntent(my_button_r_id_received_in_parameter, pendingIntent);

Set Action Solved this for me. Here's my understanding of the situation:


I have multiple widgets that have a PendingIntent attached to each. Whenever one got updated they all got updated. The Flags are there to describe what happens with PendingIntents that are exactly the same.

FLAG_UPDATE_CURRENT description reads much better now:

If the same PendingIntent you are making already exists, then update all the old ones to the new PendingIntent you are making.

The definition of exactly the same looks at the whole PendingIntent EXCEPT the extras. Thus even if you have different extras on each intent (for me I was adding the appWidgetId) then to android, they're the same.

Adding .setAction with some dummy unique string tells the OS. These are completely different and don't update anything. In the end here's my implementation which works as I wanted, where each Widget has its own configuration Intent attached:

Intent configureIntent = new Intent(context, ActivityPreferences.class);

configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

configureIntent.setAction("dummy_unique_action_identifyer" + appWidgetId);

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configureIntent,
    PendingIntent.FLAG_UPDATE_CURRENT);

UPDATE


Even better solution in case you're working with broadcasts. Unique PendingIntents are also defined by unique request codes. Here's my solution:

//Weee, magic number, just want it to be positive nextInt(int r) means between 0 and r
int dummyuniqueInt = new Random().nextInt(543254); 
PendingIntent pendingClearScreenIntent = PendingIntent.getBroadcast(context, 
    dummyuniqueInt, clearScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

I see answers but no explanations. Also none of the answers address all possible solutions, so I'll try to make that clear.

Documentation:

If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent.filterEquals, or different request code integers supplied to getActivity(Context, int, Intent, int), getActivities(Context, int, Intent[], int), getBroadcast(Context, int, Intent, int), or getService(Context, int, Intent, int).

Cause of the problem:

You create 2 notifications with 2 pending intents. Each pending intent is associated with an intent:

Intent intent = new Intent(context, testActivity.class);

However, these 2 intents are equal, therefore when your 2nd notification arrives it will launch the first intent.

Solution:

You have to make each intent unique, so that no pending intents will ever be equal. How do you make the intents unique? Not by the extras you put with putExtra(). Even if the extras are different, the intents might still be equal. To make each intent unique, you must set a unique value to the intent action, or data, or type, or class, or category, or request code: (any of those will work)

  • action: intent.setAction(...)
  • data: intent.setData(...)
  • type: intent.setType(...)
  • class: intent.setClass(...)
  • category: intent.addCategory(...)
  • request code: PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);

Note: Setting a unique request code might be tricky because you need an int, while System.currentTimeMillis() returns long, which means that some digits will be removed. Therefore I would recommend to either go with the category or the action and setting a unique string.


I had the same problem, and was able to fix it by changing the flag to:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

As documentation said use unique request code:

If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent.filterEquals, or different request code integers supplied to getActivity(Context, int, Intent, int), getActivities(Context, int, Intent[], int), getBroadcast(Context, int, Intent, int), or getService(Context, int, Intent, int).


Fwiw, I have had better luck with PendingIntent.FLAG_CANCEL_CURRENT than with PendingIntent.FLAG_UPDATE_CURRENT.