10

我有一个应用程序可以提醒人们完成任务。所以有一个PendingIntent,现在用户可以随时删除警报。在此代码中,只有一个 PendingIntent 用于多个用户警报,因此我对取消意图 extra 所在的特定警报感到困惑"pill"。不应取消剩余的警报。我对这个问题一无所知。希望我清楚。谢谢

Intent intent = new Intent(this, AlarmNotifyReceiver.class);
intent.putExtra("Name_pill", "pill");
sender = PendingIntent.getBroadcast(this,
DatabaseConstants.NOTIFICATION_ID + 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), sender);
updateTheFlag(pillName[(pillName.length-1)]);
4

5 回答 5

13

根据 Android 文档,为了停止警报,您应该Intent使用相同的数据创建一个,但不一定需要相同的附加功能:

公共无效取消(PendingIntent 操作)

删除任何具有匹配 Intent 的警报。任何类型的任何警报,其 Intent 匹配 this > one(由filterEquals(Intent)定义)都将被取消。

filterEquals(Intent)

public boolean filterEquals (Intent other)

出于意图解析(过滤)的目的,确定两个意图是否相同。> 也就是说,如果它们的操作、数据、类型、类和类别相同。这不会比较意图中包含的任何额外数据。

于 2011-08-28T08:36:14.097 回答
5

正如我在评论中所说,您似乎只需要重新创建完全相同的 PendingIntent 对象,并将相同的 Extras 放入其中。然后,你打电话

am.cancel(sender);

并且您的特定警报应该被取消。就个人而言,我找不到更好的方法。我在其他地方找到了这些信息来证实我的期望。

上面写着:

必须取消重复警报才能停止它们。AlarmManager 提供了一个 cancel() 方法,该方法需要与创建意图相同的意图类。这是您可以取消警报的方法。

alarmManager.cancel(pendingIntent);

请注意,pendingIntent 对象不需要是同一个对象。创建警报时,动作、类、类别等意图字段应相同。意图用于识别警报以取消它。

这是在重复警报的情况下,但如果我没记错的话,应该以同样的方式取消一次性警报。因为我在工作,所以我无法自己更彻底地测试它,但这应该可以。

于 2010-12-03T14:35:58.123 回答
1

我认为需要提及的requestCode参数。getBroadcast()我同意根据给定的意图取消所有警报。但是在定义PendingIntent取消时,可以使用唯一的requestCode使警报唯一。因此,只有那些具有相同意图requestCode的警报才会被取消:

int TIMER_1 = 1;
int TIMER_2 = 2;
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, AppReciever.class);
i.putExtra("timer", "one");
PendingIntent pending = PendingIntent.getBroadcast(this, TIMER_1, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending);

然后根据检查 PendingIntent 是否存在:

PendingIntent pending1 = PendingIntent.getBroadcast(this, TIMER_2, i, 
                PendingIntent.FLAG_NO_CREATE);
boolean alarmUp = (pending1 != null);

alarmUp将是错误的(注意 FLAG_NO_CREATE 用于不创建新的,如果不存在)所以尝试使用相同的requestCode

PendingIntent pending2 = PendingIntent.getBroadcast(this, TIMER_1, i, 
                PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);

alarmUp将是真的,现在尝试新的意图包含不同的额外内容:

Intent i2 = new Intent(this, AppReciever.class);
i2.putExtra("timer", "two");
pending2 = PendingIntent.getBroadcast(this, TIMER_1, i2, 
                PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);

alarmUp也将是正确的,因为iandi2是相同的,尽管额外的不是,所以现在您可以删除此警报:

am.cancel(pending2);
于 2013-02-26T15:25:27.947 回答
0

所以有一个待处理的意图,现在用户可以随时删除警报。在这段代码中,多个用户警报只有一个待处理的意图,所以我对取消附加是药丸的特定警报感到困惑

intent.putExtra("Name_pill", "pill");

额外的将无法取消您未决的意图。

pendingIntent.cancel()只会删除以相同方式触发的待处理意图,filterEquals(Intent) 并且该方法不会比较提供给意图的任何额外数据。

这是来自 android 开发者网站的内容filterEquals(Intent)

出于意图解析(过滤)的目的,确定两个意图是否相同。也就是说,如果它们的动作、数据、类型、类和类别相同。这不会比较意图中包含的任何额外数据。

如果我们考虑您的情况,当您当时将其传递Extra给意图时,您只需将唯一 ID 保存sharedpreference 在参数中给出的一些参数中,并且您应该记住一件事,ID 必须是唯一的。

并且当您想取消该警报时,只需使用该保存的 ID 传递相同的意图并取消它pendingintent

创造

preference_saved_value =  DatabaseConstants.NOTIFICATION_ID + 1
sender = PendingIntent.getBroadcast(this,
preference_saved_value, intent,
PendingIntent.FLAG_UPDATE_CURRENT)

取消

sender = PendingIntent.getBroadcast(this, 
preference_saved_value, intent,PendingIntent.FLAG_UPDATE_CURRENT);  
sender.cancel()
于 2013-04-06T06:48:20.753 回答
0

正如 android 文档中所述,未决意图的意图与 Intent.filterEquals 等效,但具有不同的请求代码被认为是不同的:

如果您确实需要同时激活多个不同的 PendingIntent 对象(例如用作同时显示的两个通知),那么您将需要确保它们有所不同,以便将它们与不同的待定意图。这可能是 Intent.filterEquals 考虑的任何 Intent 属性,或提供给 getActivity(Context, int, Intent, int)、getActivities(Context, int, Intent[], int)、getBroadcast(Context, int) 的不同请求代码整数, Intent, int) 或 getService(Context, int, Intent, int)。

因此,您可以分配不同的请求代码并根据它们取消待处理的意图,而忘记额外的。

有一个有趣的场景,我发现了这种行为:

我在我的代码中安排了一个警报并在设备上运行它,但从未取消它。然后我更改了请求代码并再次运行它。因此,创建了一个新警报。我取消了新警报,但警报仍在从以前​​的代码执行。我很困惑为什么没有取消警报。在我发现它来自具有不同请求代码的先前代码后,我卸载了该应用程序并再次安装它并解决了问题。

于 2013-07-07T19:27:57.013 回答