背景
我通过AlarmManager使用PendingIntent进行报警。
问题:
起初我认为为了取消之前的那些,我必须提供我之前用过的确切的requestCode来启动警报。
但后来我发现我错了,正如cancellation API所说:
删除具有匹配Intent的所有警报。任何类型的警报, 其Intent与此Intent匹配(由filterEquals(Intent)定义), 将被取消。
查看“filterEquals”,文档说:
为了意图的目的,确定两个意图是否相同 分辨率(过滤)。也就是说,如果他们的行动,数据,类型,类, 和类别是一样的。这不会比较任何额外的数据 包含在意图中。
所以我没有得到“requestCode”的内容......
问题:
什么是“requestCode”用于?
如果我使用相同的“requestCode”创建多个警报怎么办?他们互相覆盖了吗?
答案 0 :(得分:68)
requestCode
用于稍后检索相同的待处理目标实例(用于取消等)。答案 1 :(得分:22)
我只想添加到@Minhaj Arfin的回答
1- requestCode用于稍后获取相同的待处理意图(用于取消等)
2-是的,只要您指定与您在PendingIntent上指定的Intent相同的Receiver
,它们就会被覆盖示例:
Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, 0);
Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);
从上面的例子中,他们不会互相覆盖因为接收器不同(AlarmReceiverFirst和AlarmReceiverSecond)
Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);
Intent startIntent3 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, startIntent3, 0);
从上面的示例中,他们将互相覆盖,因为接收器相同(AlarmReceiverSecond)
答案 2 :(得分:3)
实际上,documentation清楚地说明了请求代码的用途:
如果您确实需要在以下位置激活多个不同的PendingIntent对象 同一时间(例如用作同时显示的两个通知) 同时),那么您将需要确保有一些东西 他们的不同之处在于将他们与不同的人联系在一起 待定意向。这可能是由 Intent#filterEquals(Intent)或不同的请求代码整数 提供给getActivity(Context,int,Intent,int), getActivities(Context,int,Intent [],int),getBroadcast(Context,int, Intent,int)或getService(Context,int,Intent,int)。
由于似乎仍然不清楚,让我尝试解释一下:
要使用PendingIntent
对象时,您不仅要实例化一个对象。相反,您可以使用PendingIntent
静态方法(getActivity
,getBroadcast
,getService
等从系统中获取一个)。系统保留了一堆PendingIntent实例并给您一个。它为您提供哪一个,取决于您传递给这些getter方法的输入参数。这些输入参数是:Context
,即意图的目标接收者,要使用的Intent
,requestCode
和flags
。当您传递相同的Context
,相同的requestCode
和相同的Intent(表示一个filterEquals
与另一个Intent的Intent)时,您将获得相同的PendingIntent
对象。关键是系统希望拥有尽可能少的PendingIntent
对象,因此它倾向于尽可能多地重用现有对象。
例如,对于两个不同的日期,您有两个日历通知。当您单击其中之一时,您希望您的应用打开到该通知的相应日期。在这种情况下,您具有相同的Context
目标,并且传递的Intent
对象仅在EXTRA_DATA(用于指定应打开的日期)上有所不同。如果在获取requestCode
对象时提供了相同的PendingIntent
,那么最终将得到相同的PendingIntent
对象。因此,在创建第二个通知时,您将用新的EXTRA_DATA替换旧的Intent
对象,最后得到两个指向同一日期的通知。
如果要具有两个不同的PendingIntent
对象(如在此情况下一样),则在获取requestCode
对象时应指定一个不同的PendingIntent
。
答案 3 :(得分:1)
在我的情况下,我想使用两个不同的意图打开同一活动,因此,如果托盘中有两个或多个FCMS,则其中任何一个只会打开另一个而不会,所以我更改了待定意图的请求代码,然后它起作用了。
PendingIntent pendingIntent =
PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
答案 4 :(得分:0)
requestCode
的一个重要问题是使用小部件,这将严重困扰您的应用。
如果requestCode
相同,则小部件在电话重启后将无法工作。
这意味着您必须在小部件的pendingIndent
上设置的remoteViews
必须设置唯一的requestCode,通常是带数字的widgetId。
答案 5 :(得分:0)
在构建 PendingIntent 时,您需要提供一个名为 requestCode 的整数。官方文档指出这是“发送者的私人请求代码”。但是,请求代码也是区分 PendingIntent 实例的基本方式。你看,getBroadcast() 方法不仅仅是一个创建 PendingIntent 实例的静态工厂