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
从实例化的activity
传递到UploadManager
。 函数displayNotification()
在同一个AsyncTask
运行的UploadManager中的函数被多次调用。
编辑1:我忘了提及,我作为一个extra
传递string响应到Intent intent
。
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);
这会产生很大的差异,因为我需要额外的“响应”来反映通知创build时的string响应。 相反,使用PendingIntent.FLAG_UPDATE_CURRENT
,额外的“响应”反映了最后一次调用displayNotification()
String响应。
我知道这是通过阅读FLAG_UPDATE_CURRENT
上的文档。 不过,目前我不清楚如何解决这个问题。
不要对PendingIntent.getActivity使用Intent.FLAG_ACTIVITY_NEW_TASK ,请改用FLAG_ONE_SHOT
从评论复制:
然后在Intent上设置一些虚拟操作,否则额外的操作会被丢弃。 例如
intent.setAction(Long.toString(System.currentTimeMillis()))
在HomeScreen
Widget上,每个Button
在使用RemoteViews
和几个不同的Intents
。 工作时添加这些:
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);
设置行动解决这个给我。 这是我对情况的理解:
我有多个小工具,每个都有一个PendingIntent。 每当有人更新,他们都得到更新。 标志在那里描述了PendingIntents发生的事情是完全一样的。
FLAG_UPDATE_CURRENT描述现在读得好多了:
如果您正在创build的PendingIntent已经存在,那么将所有的旧PendingIntent更新为您正在创build的新的PendingIntent。
完全相同的定义看起来整个PendingIntent除了额外的。 因此,即使你有不同的额外的每个意图(对我来说,我是添加appWidgetId),然后到Android,他们是一样的。
添加.setAction与一些虚拟的唯一string告诉操作系统。 这些是完全不同的,不更新任何东西。 最后,这里是我的实现,这是我想要的,每个Widget都有自己的configurationIntent附:
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
更好的解决scheme,如果你正在使用广播。 唯一的PendingIntents也由唯一的请求代码定义。 这是我的解决scheme:
//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);
我有同样的问题,并能够解决它通过更改标志为:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Fwiw, PendingIntent.FLAG_CANCEL_CURRENT
比PendingIntent.FLAG_UPDATE_CURRENT
有更好的运气。
正如文件说的使用唯一的请求代码:
如果您确实需要同时激活多个不同的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)。
我有同样的问题,我通过以下步骤进行了修复
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);
我希望能和你一起工作
我看到答案,但没有解释。 也没有答案处理所有可能的解决scheme,所以我会尽量说清楚。
文档:
如果您确实需要同时激活多个不同的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)。
问题的原因:
您创build2个未决意图的通知。 每个未决意图都与一个意图相关联:
Intent intent = new Intent(context, testActivity.class);
然而,这两个意图是平等的,因此当你的第二个通知到达时,它将启动第一个意图。
解:
你必须使每个意图都是唯一的,这样就不会有任何等待的意图。 你如何使意图独特? 而不是你用putExtra()
放置的额外的东西。 即使演员不同,意图也可能是平等的。 为了使每个意图唯一,您必须为意向操作,数据或types,类别,类别或请求代码设置一个唯一的值:(其中任何一个都可以)
- 操作:
intent.setAction(...)
- data:
intent.setData(...)
- 键入:
intent.setType(...)
- class:
intent.setClass(...)
- category:
intent.addCategory(...)
- 请求代码:
PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);
注意 :设置一个唯一的请求代码可能会很棘手,因为你需要一个int,而System.currentTimeMillis()
返回long,这意味着一些数字将被删除。 因此,我build议要么与类别或行动,并设置一个独特的string。
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
在PendingIntent中是两个int参数,第二个和最后一个。 第二个是“请求代码”,它必须是唯一的数字(例如你的通知的id),否则如果(在你的例子中它等于零,它总是会被覆盖)。
// 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());
要发送数据额外正确,你应该发送与挂起的意图通知id像这样:PendingIntent pendingIntent = PendingIntent.getActivity(context, (int)System.currentTimeMillis() ,intent,PendingIntent.FLAG_UPDATE_CURRENT);
我有同样的问题,并使用PendingIntent.html.FLAG_UPDATE_CURRENT来解决它。
我已经检查了源代码。 在ActivityManagerService.java中 ,关键的方法如下。 标志为PendingIntent.FLAG_UPDATE_CURRENT且updateCurrent为true时。 一些额外的将被新的取代,我们将得到一个替代PendingIntent。
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); }
我有同样的问题,并能够修改它通过更改标志为:
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(); }