如何创建不同的pendingintent 使filterEquals() 返回false?
Posted
技术标签:
【中文标题】如何创建不同的pendingintent 使filterEquals() 返回false?【英文标题】:How to create different pendingintent so filterEquals() return false? 【发布时间】:2011-11-21 17:38:03 【问题描述】:我正在使用 AlarmManager 来设置重复意图,但它造成了一些小麻烦,所以希望任何人都可以提供帮助。
总结
有 2 个待处理的意图。一个每天跑1000,另一个每天跑2000。每个都包含来自数据库的行 id 用于识别目的。代码如下所示:
Intent i = new Intent(mContext, ScheduleReceiver.class);
i.putExtra(RuleDBAdapter.KEY_ROWID, (int)taskId);
PendingIntent pi =PendingIntent.getBroadcast(...);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
删除:
问题是当我们需要删除其中一个时。删除待处理意图的正确方法是设置一个相同的意图,然后从 AlarmManager 调用取消。
android 文档:
public void cancel (PendingIntent operation) 删除任何具有匹配 Intent 的警报。任何类型的警报,其 Intent 与此匹配(由 filterEquals(Intent) 定义)都将被取消。
public boolean filterEquals (Intent other) 出于意图解析(过滤)的目的,确定两个意图是否相同。也就是说,如果它们的动作、数据、类型、类和类别相同。这不比较意图中包含的任何额外数据。
所以在上面的例子中,如果我做了一个相同的意图然后取消,上述两个意图将被取消,因为它们来自相同的类/相同的动作等(除了“额外" data 是 rowId 但filterEquals
不关心额外数据)。
有什么解决方法吗?
【问题讨论】:
【参考方案1】:您可以在创建待处理意图时尝试使用 requestCode 参数:
PendingIntent pi =PendingIntent.getBroadcast(mContext, yourUniqueDatabaseId,i,PendingIntent.FLAG_ONE_SHOT);
这应该创建一个用于匹配目的的唯一 Intent..
【讨论】:
谢谢!很有可能它会起作用。不知道这么简单。 :) 我希望他们能更新文档,因为当你试图让某些东西正常工作时,将它说为“未使用”的 requestCode 真的很吓人。 小心:requestCode 被定义为 int 而通常 (sqlite) 行 ID 很长。 你确定可以使用requestCode吗?查看文档,他们谈论了能够区分它们的各种事物,但不是 requestCode:developer.android.com/reference/android/app/… -> ... -> developer.android.com/reference/android/app/… ->developer.android.com/reference/android/content/…【参考方案2】:public boolean filterEquals(Intent other) 比较action、data、type、package、component、category,但是不比较extra,所以extra之间的区别无法区分Intent。尝试为这些 Intent 设置不同的数据,这些数据可能是微不足道的 Uris。
尝试阅读源代码以获取更多信息。
【讨论】:
【参考方案3】:尝试在意图中放置一个虚拟动作。 例如。
myIntent.setAction(""+System.currentTimeMillis());
这将导致 filterEquals 返回 false。
我需要一个类似的解决方案来从多个号码发送短信通知, 为了允许通知以不同的数字启动短信线程查看器。
【讨论】:
【参考方案4】:将任务 ID 和时间戳放入意图的操作中。这样,您将待处理的 Intent 与任务 ID 相关联,并且 Intent 在过滤方面仍然会有所不同。
intent.setAction("ACTION_" + taskId + "_" + currentTimestamp);
【讨论】:
【参考方案5】:在我的情况下,我没有一个好的方法来为我的待处理意图生成唯一键,所以我所做的就是将自定义数据添加到生成的意图中。
一旦你开始填充 data 属性,你必须记住在 android manifest 中的 intent-filter 中添加一个 data 参数。如果您不这样做,它将不会触发您的自定义接收器。
例子:
意图
Intent intent = new Intent(reminderFire);
intent.addCategory(reminderCategory);
Uri.Builder builder = new Uri.Builder();
builder.scheme(context.getString(R.string.scheme));
builder.authority(context.getString(R.string.intent_filter_reminder_host));
builder.appendQueryParameter("oid", Reminder.getOid());
intent.setData(builder.build());
AndroidManifest 条目
<receiver
android:name=".client.MyReminder"
android:enabled="true"
>
<intent-filter>
<action android:name="com.example.client.reminder.fire"/>
<action android:name="com.example.client.reminder.category"/>
<data
android:host="@string/intent_filter_reminder_host"
android:scheme="@string/scheme" />
</intent-filter>
</receiver>
通过这样做,您还可以在将 Intent 添加为待处理 Intent 之前测试其唯一性,这在您进行单元测试时非常有用。
【讨论】:
以上是关于如何创建不同的pendingintent 使filterEquals() 返回false?的主要内容,如果未能解决你的问题,请参考以下文章