【问题标题】:Issue with cancelling the AlarmManager - PendingIntent取消 AlarmManager 的问题 - PendingIntent
【发布时间】:2010-09-09 15:34:41
【问题描述】:

我有一个应用程序可以提醒人们完成任务。所以有一个PendingIntent,现在用户可以随时删除警报。在这段代码中,只有一个 PendingIntent 用于多个用户警报,所以我对取消意图额外为"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)]);

【问题讨论】:

  • 我也在寻找这个问题的类似答案。我正在做一些与你非常相似的事情,但我似乎无法让它发挥作用。我现在的理解是您需要使用 am.cancel(pendingIntent) 意味着您需要初始化一个与您在此处创建的相同的 pendingIntent。但是,这似乎对我不起作用。任何能回答这个问题的人肯定会得到我的支持:)

标签: android android-pendingintent


【解决方案1】:

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

public void cancel(PendingIntent 操作)

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

filterEquals(Intent)

public boolean filterEquals (Intent other)

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

【讨论】:

  • 那么,如果你有 2 个PendingIntent,它们是在不同时间创建的,做着完全相同的事情,应该用什么来区分它们?
【解决方案2】:

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

am.cancel(sender);

并且应该取消您的特定警报。就个人而言,我找不到更好的方法。我发现此信息以确认我的期望elsewhere

上面写着:

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

alarmManager.cancel(pendingIntent);

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

这是在重复警报的情况下,但如果我没记错的话,应该以同样的方式取消一次性警报。由于我在工作,我无法独自对其进行更彻底的测试,但这应该可以。

【讨论】:

  • 根据 Android 文档,为了停止警报,您应该使用相同的数据创建一个 Intent,但不一定需要相同的附加功能: public void cancel (PendingIntent operation) 删除任何警报具有匹配的意图。任何类型的警报,其 Intent 与此匹配(由 filterEquals(Intent) 定义)都将被取消。
【解决方案3】:

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

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);

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

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

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

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

alarmUp 将为 true,现在尝试使用新意图包含不同的额外内容:

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 也将是 true,因为 ii2 是相同的,尽管额外的不是,所以现在您可以删除此警报:

am.cancel(pending2);

【讨论】:

    【解决方案4】:

    所以有一个待处理的意图,现在用户可以在何时删除警报 他想要。 Ib 这段代码只有一个待定意图 多个用户警报,因此我对取消该特定警报感到困惑 额外的东西是药丸的警报

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

    额外的不会取消你的未决意图。

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

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

    根据意图的目的确定两个意图是否相同 分辨率(过滤)。也就是说,如果他们的动作、数据、类型、类、 和类别是一样的。这不会比较任何额外的数据 包含在意图中。

    如果我们考虑您的情况,当您当时将 Extra 传递给意图时,您只需要在参数中给出的一些 sharedpreference 中保存唯一 ID,您应该记住一件事,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()
    

    【讨论】:

      【解决方案5】:

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

      如果您确实需要多个不同的 PendingIntent 对象在 同时(例如用作两个都显示的通知 同时),那么你需要确保有一些东西 他们的不同之处在于将它们与不同的 待定意图。这可能是考虑的任何 Intent 属性 Intent.filterEquals,或提供给的不同请求代码整数 getActivity(上下文,int,Intent,int),getActivity(上下文,int, Intent[], int), getBroadcast(Context, int, Intent, int), 或 getService(Context, int, Intent, int).

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-07
        • 1970-01-01
        相关资源
        最近更新 更多