PendingIntent works correctly for the first notifi

2019-01-05 09:31发布

  protected void displayNotification(String response) {
    Intent intent = new Intent(context, testActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

    Notification notification = new Notification(R.drawable.icon, "Upload Started", System.currentTimeMillis());
    notification.setLatestEventInfo(context, "Upload", response, pendingIntent);

    nManager.notify((int)System.currentTimeMillis(), notification);
}

This function will be called multiple times. I would like for each notification to launch testActivity when clicked. Unfortunately, only the first notification launches testActivity. Clicking on the rest cause the notification window to minimize.

Extra information: Function displayNotification() is in a class called UploadManager. Context is passed into UploadManager from the activity that instantiates. Function displayNotification() is called multiple times from a function, also in UploadManager, that is running in an AsyncTask.

Edit 1: I forgot to mention that I am passing String response into Intent intent as an extra.

  protected void displayNotification(String response) {
    Intent intent = new Intent(context, testActivity.class);
    intent.putExtra("response", response);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

This makes a big difference because I need the extra "response" to reflect what String response was when the notification was created. Instead, using PendingIntent.FLAG_UPDATE_CURRENT, the extra "response" reflects what String response was on the last call to displayNotification().

I know why this is from reading the documentation on FLAG_UPDATE_CURRENT. However, I am not sure how to work around it at the moment.

13条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-05 10:07
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

In PendingIntent is two int parameters, second one and the last one. Second one is "request code" and it must be unicue number (for example id of your notifiction), else if (as in your example it equals zero, it always will be overwritten).

查看更多
家丑人穷心不美
3楼-- · 2019-01-05 10:09

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);
查看更多
做自己的国王
4楼-- · 2019-01-05 10:10

to send data extra correctly you should send with pending intent the notification id like this: PendingIntent pendingIntent = PendingIntent.getActivity(context, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);

查看更多
Juvenile、少年°
5楼-- · 2019-01-05 10:13

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).

查看更多
你好瞎i
6楼-- · 2019-01-05 10:14

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);
查看更多
走好不送
7楼-- · 2019-01-05 10:14

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

查看更多
登录 后发表回答