【问题标题】:AlarmManager.set(...) behavior not matching documentation. Am I doing something wrong?AlarmManager.set(...) 行为与文档不匹配。难道我做错了什么?
【发布时间】:2011-10-31 18:31:08
【问题描述】:

我正在使用此代码设置警报

//in onCreate()
mAlarmManager = (AlarmManager) getApplicationContext()
            .getSystemService(ALARM_SERVICE);

//called for each timer I schedule
Intent intent = new Intent (Intents.MY_INTENT_ACTION);
PendingIntent pendIntent = PendingIntent.getBroadcast(
    getApplicationContext(), alert.getID(), 
    intent, PendingIntent.FLAG_ONE_SHOT);
long delay = 1000 * alert.getDuration();
Calendar cal = Calendar.getInstance();
mAlarmManager.set(AlarmManager.RTC_WAKEUP,
    cal.getTimeInMillis() + delay, pendIntent);

但我看到的行为与我在文档1 中看到的不符,

public void set(int type, long triggerAtTime, PendingIntent operation)

如果已经为同一个 IntentSender 安排了警报,它将首先被取消...如果已经为这个 Intent 安排了警报(两个 Intent 的相等性由 filterEquals(Intent) 定义),那么它将被删除并替换为这个...

这表明为已经报警的意图调用 set(int type, long triggetAtTime, PendingIntent 操作) 应该替换该意图的旧报警。我没有看到任何警报被丢弃。相反,我设置的每个警报都会触发,尽管待处理的 Intent 触发的 Intent 都应该匹配(通过 filterEquals(intent)),因为我在每个 Intent 上设置的所有内容都是相同的操作。

是我做错了什么,还是 API 的行为不像记录的那样?

注意:将 PendingIntent 实例化更改为

PendingIntent pendIntent = PendingIntent.getBroadcast(
getApplicationContext(), CONSTANT_ID,
intent, PendingIntent.FLAG_ONE_SHOT);

按预期运行,删除任何已设置的警报,并将其替换为新警报。

【问题讨论】:

  • 尝试摆脱alarm.getID()并使用0
  • 在下面查看我对 jong 回答的评论。

标签: android alarmmanager alarms


【解决方案1】:

可能是因为您为每个警报提供了不同的 ID(alert.getID() 是否提供不同的 ID?)。根据文档,它不应该重要,但您仍然应该尝试。

如果它也不起作用,请为您上次设置的闹钟保留一个参考,当您需要取消它时,自己取消它然后设置下一个。

【讨论】:

  • 大概就是这样。这非常重要。不同的 ID 意味着它在技术上是不同的 Intent。
  • 这实际上是我正在寻找的功能,但它与我对文档的期望不符,所以它让我怀疑我的理解在某个地方存在缺陷。我在文档引用中添加了另一句话,表明重用相同 IntentSenders (PendingIntents) 的概念是单独解决的,并且 afaik 正常运行。我的问题是 AlarmManager 是查看 PendingIntent 生成的意图,还是仅查看 PendingIntent 的唯一性
  • 文档说它通过 filterEquals 计算意图。 filterEquals 与 PendingIntent 无关,所以我不确定它是否重要。但他应该测试一下。
  • 尽量保留对您上次设置的闹钟的引用,以便在需要时取消它。
  • 我猜文档有问题。我发现 AudioManager 的文档“有点”错误,但我设法通过持有对我的 AudioManager 的静态引用来修复它。尝试保持对您的 AlarmManager 的静态引用。我在我的一个应用程序中持有对 AlarmManager 的静态引用,它可以毫无问题地取消匹配的意图。
【解决方案2】:

您是否尝试过使用 PendingIntent 标志:PendingIntent.FLAG_UPDATE_CURRENT 而不是 PendingIntent.FLAG_ONE_SHOT

【讨论】:

  • 我想我们永远不会知道
【解决方案3】:

似乎一致认为,AlarmManager.set() 的文档以及声称 Intent(不仅仅是包装 PendingIntent)的其他 AlarmManager 方法被比较以检查是否已经设置了特定警报。

不要依赖 AlarmManager 匹配 Intent,而是依赖 PendingIntent 的匹配,这似乎像宣传的那样工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2021-10-26
    • 2013-02-27
    • 2023-03-13
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多