PendingInent 创建的 Android 任务无法再次使用 pendingIntent 启动另一个活动
Posted
技术标签:
【中文标题】PendingInent 创建的 Android 任务无法再次使用 pendingIntent 启动另一个活动【英文标题】:Android Task Created by PendingInent cannot start another activity with pendingIntent again 【发布时间】:2021-12-26 01:26:36 【问题描述】:我有 2 个活动:主要(将与警报管理器安排通知)和消息(处理用户导航或通知)。 Message 上没有设置启动模式和标志。消息由用户导航或通知打开。
正常的控制流程:
(主屏幕) -> (user) -> Main 的新任务 -> (user) -> new Message -> (notification) -> new Message -> (notification) -> new Message -> (用户)-> 新消息
当应用程序未加载并且通过消息通知启动新任务时。流程没问题:
(主屏幕)->(通知)-> 消息的新任务 ->(用户)-> 新消息
当第二个通知被点击时,问题就出现了,它没有被正确处理。第二个通知预计会有新消息。
(主屏幕)->(通知)-> 消息的新任务 ->(通知)-> X 现在什么都没有,但期待新消息
最后一个通知未决意图无法启动消息(没有 OnCreate,没有 OnNewIntent)。也没有新的任务开始处理它。如果任务在后台,通知挂起意图将把任务带到前台(但没有新的活动)。结果是,对于由挂起意图启动的任务,任何进一步的挂起意图都不会创建新的活动。不确定这是否与未决的意图安全问题或其他问题有关。
当任务由待定意图启动时,如何启动带有通知待定意图的新活动消息?任何帮助将不胜感激。
谢谢,
尼克
代码是用 Xamarin 编写的,供参考:
设置闹钟的代码,context就是Activity的上下文。
Intent intentScheduleReminder = new Intent(context, typeof(BroadcastReceiver));
intentScheduleReminder.SetAction(PlatformConstants.NotificationActionShow);
intentScheduleReminder.PutExtra(PlatformConstants.ScheduleReminderId, scheduleReminder.Id);
PendingIntent intentAlarm = PendingIntent.GetBroadcast(context, scheduleReminder.Id, intentScheduleReminder, PendingIntentFlags.CancelCurrent);
Java.Util.Calendar calendar = DroidUtility.ConvertDateTimeToCalendar(scheduleReminder.ScheduleDateTime);
AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, calendar.TimeInMillis, intentAlarm);
发送通知的代码。 Pending Intent 是使用 BroadcastReceiver.OnReceive 的上下文创建的
var builder = new NotificationCompat.Builder(Application.Context, PlatformConstants.NotificationChannelIdBillReminder)
.SetContentTitle(appNotification.Title)
.SetContentText(appNotification.Message)
.SetSmallIcon(Resource.Drawable.ic_appicon_24dp)
.SetLargeIcon(largeIconBitmap)
.SetAutoCancel(true)
.SetOnlyAlertOnce(true);
Intent intent = new Intent((Context)BroadcastContext, typeof(InfiniteScrollingParentFsActivity));
intent.PutExtra(……
PendingIntent pendingIntent = PendingIntent.GetActivity((Context)BroadcastContext, notificationId, intent, 0);
builder.SetContentIntent(pendingIntent);
Notification notification = builder.Build();
NotificationManager notificationManager = (NotificationManager)Application.Context.GetSystemService(Context.NotificationService);
notificationManager.Notify(notificationId, notification);
【问题讨论】:
【参考方案1】:仔细阅读the documentation for PendingIntent。尤其是这部分:
由于这种行为,重要的是要知道两个 Intent 何时被认为是相同的,以便检索 PendingIntent。人们犯的一个常见错误是创建多个 PendingIntent 对象,其 Intent 仅在其“额外”内容上有所不同,期望每次都获得不同的 PendingIntent。这不会发生。 Intent 中用于匹配的部分与 Intent.filterEquals 定义的部分相同。如果您使用两个根据 Intent.filterEquals 等效的 Intent 对象,那么您将获得相同的 PendingIntent。
您的通知总是触发相同的 Intent:
Intent intent = new Intent((Context)BroadcastContext, typeof(InfiniteScrollingParentFsActivity));
intent.PutExtra(……
PendingIntent pendingIntent = PendingIntent.GetActivity((Context)BroadcastContext, notificationId, intent, 0);
因此,如果存在相同的 Activity,它总是会重新打开它。
您可能希望使您的意图独一无二,以便每个意图都代表一条消息。您可以通过为意图的 data
字段设置一个唯一值来做到这一点:
Intent intent = new Intent((Context)BroadcastContext, typeof(InfiniteScrollingParentFsActivity));
intent.PutExtra(……
intent.SetData(something that uniquely ids this message here) <----
PendingIntent pendingIntent = PendingIntent.GetActivity((Context)BroadcastContext, notificationId, intent, 0);
【讨论】:
以上是关于PendingInent 创建的 Android 任务无法再次使用 pendingIntent 启动另一个活动的主要内容,如果未能解决你的问题,请参考以下文章