PendingIntent对第一个通知正常工作,但对其余通知不正确

时间:2010-07-02 19:11:29

标签: android notifications android-pendingintent

  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);
}

此功能将被多次调用。我希望每个notification在点击时启动testActivity。不幸的是,只有第一个通知启动testActivity。单击其余部分会使通知窗口最小化。

额外信息:函数displayNotification()位于名为UploadManager的类中。 Context从实例化的UploadManager传递到activity。函数displayNotification()多次从函数调用,也在UploadManager中调用,该函数在AsyncTask中运行。

编辑1:我忘了提到我将字符串响应作为Intent intent传递给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);

这有很大的不同,因为我需要额外的“响应”来反映创建通知时的字符串响应。相反,使用PendingIntent.FLAG_UPDATE_CURRENT,额外的“响应”反映了最后一次调用displayNotification()时字符串响应的内容。

我知道为什么这是通过阅读FLAG_UPDATE_CURRENT上的文档。但是,我现在还不确定如何解决这个问题。

14 个答案:

答案 0 :(得分:110)

不要将Intent.FLAG_ACTIVITY_NEW_TASK用于PendingIntent.getActivity,而是使用FLAG_ONE_SHOT


从评论中复制:

然后在Intent上设置一些虚拟动作,否则会删除额外的动作。例如

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

答案 1 :(得分:58)

RemoteViews Widget上的每个IntentsButton和几个不同的HomeScreen进行了争吵。 添加这些后工作:

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

答案 2 :(得分:40)

Set Action为我解决了这个问题。以下是我对情况的理解:


我有多个小部件,每个小部件都附有PendingIntent。每当有人更新,他们都会得到更新。 Flags用于描述与PendingIntents完全相同的情况。

FLAG_UPDATE_CURRENT描述现在读得更好:

如果您正在制作的PendingIntent相同,则将所有旧的PendingIntent更新为您正在制作的新PendingIntent。

完全相同的定义着眼于整个PendingIntent EXCEPT附加内容。因此,即使你对每个意图都有不同的额外内容(对我来说我是在添加appWidgetId)然后到android,它们也是一样的。

使用一些虚拟唯一字符串添加.setAction会告诉操作系统。这些完全不同,不会更新任何内容。最后这里是我的实现,它按照我的意愿工作,每个Widget都有自己的配置Intent附加:

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

更新


如果你正在使用广播,那就更好了解决方案。 Unique PendingIntents也由唯一的请求代码定义。这是我的解决方案:

//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);

答案 3 :(得分:13)

我遇到了同样的问题,并且能够通过将标志更改为:

来修复它
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

答案 4 :(得分:13)

我看到答案但没有解释。此外,没有一个答案能够解决所有可能的解决方案,所以我试着说清楚。

<强>文档

  

如果您确实需要多个不同的PendingIntent对象同时处于活动状态(例如用作同时显示的两个通知),那么您需要确保关联它们的某些内容有所不同他们有不同的PendingIntents。这可能是Intent.filterEquals考虑的任何Intent属性,或者提供给getActivity(Context,int,Intent,int),getActivities(Context,int,Intent [],int),getBroadcast(Context,int)的不同请求代码整数。 ,Intent,int)或getService(Context,int,Intent,int)。

问题原因:

您可以使用2个待处理意图创建2个通知。每个待处理的意图都与意图相关联:

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

但是,这两个意图相同,因此当您的第二个通知到达时,它将启动第一个意图。

<强>解决方案:

你必须使每个意图都是唯一的,这样任何未决的意图都不会相等。你如何使意图独特?不是你用putExtra()添加的额外内容。即使额外的不同,意图可能仍然相等。要使每个intent都是唯一的,您必须为intent操作或数据,类型,类或类别或请求代码设置唯一值:(其中任何一个都可以工作)

  • 行动:intent.setAction(...)
  • 数据:intent.setData(...)
  • 输入:intent.setType(...)
  • class:intent.setClass(...)
  • 类别:intent.addCategory(...)
  • 请求代码:PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);

注意:设置唯一的请求代码可能会很棘手,因为您需要一个int,而System.currentTimeMillis()返回long,这意味着某些数字将被删除。因此,我建议您使用类别操作并设置唯一字符串。

答案 5 :(得分:8)

正如文档所说,使用唯一的请求代码:

  

如果您确实需要多个不同的PendingIntent对象,请执行此操作   同时(例如使用两个显示的通知   在同一时间),那么你需要确保有一些东西   将他们与不同的人联系起来是不同的   PendingIntents。这可以是所考虑的任何Intent属性   Intent.filterEquals,或提供给的不同请求代码整数   getActivity(Context,int,Intent,int),getActivities(Context,int,   Intent [],int),getBroadcast(Context,int,Intent,int)或   getService(Context,int,Intent,int)。

答案 6 :(得分:7)

Fwiw,PendingIntent.FLAG_CANCEL_CURRENTPendingIntent.FLAG_UPDATE_CURRENT好运。

答案 7 :(得分:4)

我有同样的问题,我通过以下步骤修复它

1)清除任何意图标志

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

2)通过以下代码插入intent.setAction

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

3)对于Pendingintent,插入以下代码

   PendingIntent Pintent = PendingIntent.getActivity(ctx,0, intent,PendingIntent.FLAG_UPDATE_CURRENT);

我希望与你合作

答案 8 :(得分:1)

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

在PendingIntent中有两个int参数,第二个参数和最后一个参数。第二个是“请求代码”,它必须是unicue数字(例如你的通知的id),否则如果(在你的例子中它等于零,它总是会被覆盖)。

答案 9 :(得分:0)

// Use pending Intent and  also use unique id for display notification....
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager = (NotificationManager)  sqlitewraper.context.getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(id, builder.build());

答案 10 :(得分:0)

要正确发送数据,您应该使用挂起的意图发送通知ID,如下所示: PendingIntent pendingIntent = PendingIntent.getActivity(context,(int)System.currentTimeMillis(),intent,PendingIntent.FLAG_UPDATE_CURRENT);

答案 11 :(得分:0)

我遇到同样的问题,并使用PendingIntent.html.FLAG_UPDATE_CURRENT来修复它。

我检查了源代码。在ActivityManagerService.java中,关键方法如下。当标志为PendingIntent.FLAG_UPDATE_CURRENT且updateCurrent为true时。一些额外的内容将被new替换,我们将获得一个替换的PendingIntent。

&#13;
&#13;
    IIntentSender getIntentSenderLocked(int type, String packageName,
            int callingUid, int userId, IBinder token, String resultWho,
            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
            Bundle bOptions) {

// ... omitted

        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
                |PendingIntent.FLAG_UPDATE_CURRENT);

        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
                type, packageName, activity, resultWho,
                requestCode, intents, resolvedTypes, flags, bOptions, userId);
        WeakReference<PendingIntentRecord> ref;
        ref = mIntentSenderRecords.get(key);
        PendingIntentRecord rec = ref != null ? ref.get() : null;
        if (rec != null) {
            if (!cancelCurrent) {
                if (updateCurrent) {
                    if (rec.key.requestIntent != null) {
                        rec.key.requestIntent.replaceExtras(intents != null ?
                                intents[intents.length - 1] : null);
                    }
                    if (intents != null) {
                        intents[intents.length-1] = rec.key.requestIntent;
                        rec.key.allIntents = intents;
                        rec.key.allResolvedTypes = resolvedTypes;
                    } else {
                        rec.key.allIntents = null;
                        rec.key.allResolvedTypes = null;
                    }
                }
                return rec;
            }
            rec.canceled = true;
            mIntentSenderRecords.remove(key);
        }
&#13;
&#13;
&#13;

答案 12 :(得分:0)

在创建 PendingIntent 对象时,我们调用 PendingIntent.getActivity(mContext, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);

所以这里使用下面的代码来生成 PendingIntent 并将这个意图发送到通知。因此,当您收到另一个通知时,该通知将具有唯一的 requestCode 以仅获取该通知的数据。

Random objRandom = new Random();
final PendingIntent resultPendingIntent =
        PendingIntent.getActivity(
                mContext,
                objRandom.nextInt(100),
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

答案 13 :(得分:-5)

我遇到了同样的问题,并且能够通过将标志更改为:

来修复它
LayoutInflater factory = LayoutInflater.from(this);            
      final View textEntryView = factory.inflate(R.layout.appointment, null);
      AlertDialog.Builder bulider= new AlertDialog.Builder(PatientDetail.this);
      final AlertDialog alert=bulider.create();


        bulider.setTitle("Enter Date/Time");
        bulider.setView(textEntryView);
        bulider.setPositiveButton("Save", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                      EditText typeText=(EditText) textEntryView.findViewById(R.id.Editdate);
                      EditText input1 =(EditText) textEntryView.findViewById(R.id.Edittime);
                      getDateAndTime(typeText.getText().toString(),input1.getText().toString());
                }
            });
        bulider.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

        bulider.show();

    }