【问题标题】:How are past alarms delivered by the AlarmManager?AlarmManager 如何传递过去的警报?
【发布时间】:2010-12-11 23:07:16
【问题描述】:

我有一个关于在 AlarmManager 中设置警报的问题。我在文档中发现了一些我不理解的东西(见下文)。我想设置 10 个触发铃声模式的警报,它们交替静音和正常触发,所有的触发时间都不同。现在设备进入睡眠状态,并在所有 10 个警报都过期后再次激活。然后 AlarmManager 会立即广播警报吗?会不会只有第 10 个(铃声模式呢)?

警报意图通过 称为 int 类型的额外数据 Intent.EXTRA_ALARM_COUNT 那个 表示过去多少次报警事件 已经累积成这个意图 播送。重复出现的警报 没有送达,因为电话是 睡着的计数可能大于 交付时一个。

【问题讨论】:

    标签: android alarmmanager alarm


    【解决方案1】:

    最不为人知的一件事(主要是因为 Android 文档告诉它的"not used at the moment")是,如果 requestCode 不同,PendingIntent 将不会被重用。因此,请改为创建请求代码为 0 的 PI:

        PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 
    

    您可以实现一个计数器并执行以下操作:

        PendingIntent pendingIntent = PendingIntent.getService(context, counter, intent, 0); 
    

    我知道这适用于 SMS 传递/发送的通知 PendingIntents,您会遇到同样的问题:如果 PendingIntent 被重复使用并且您有超过 1 个未完成的通知,您将不知道它是针对哪条 SMS。 但很有可能这也适用于突出的警报 PendingIntent。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      据我了解,在使用警报管理器安排警报时,您必须提供 PendingIntent 实例。

      有两种类型的闹钟,一种即使手机处于睡眠状态或锁定状态也会唤醒并继续工作,另一种则不会。

      此外,如果您要一次安排 10 件事情,AlarmManager 将用新的一项替换现有的 Scheduled Pending 意向,除非您给它不同的意向操作。当我使用警报时,我总是使用 sqlite 数据库来排队我想按某个计划执行的作业。从那里我会一次安排一个警报,因为当蜂鸣器响起时它们都执行相同的 Intent。

      如果您安排了一个重复发生的警报并且当用户设备处于睡眠状态时它会多次响起,那么 EXTRA_ALARM_COUNT 额外功能将会发挥作用。当手机唤醒时,它将重播过去排队的任何内容。在这种情况下,您的待处理意图将触发并具有您的警报被跳过多少次的值,因为它是在调用 set 方法时使用 RTC 或 ELAPSED_REALTIME 作为类型构造的。

      这是我通常如何与 AlarmManger 交互的示例

      protected void scheduleNext(Context context) {
          AlarmManager alarmManager = getAlarmManager();
          Intent intent = new Intent(MyIntent.ACTION_DO_WORK);
          PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 
      
          String where = Queue.SCHEDULED_DATE + "= (select min(" + Queue.SCHEDULED_DATE + ") from queue where " + Queue.COMPLETED_DATE + " is null)";
          Cursor cursor = context.getContentResolver().query(Queue.CONTENT_URI, Queue.PROJECTION, where, null, null);
      
          if (cursor.moveToFirst()) {
              int id = cursor.getInt(cursor.getColumnIndex(Queue._ID));
              long when = cursor.getLong(cursor.getColumnIndex(Queue.SCHEDULED_DATE));
              alarmManager.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
          }   
      
          cursor.close();
      }
      

      【讨论】:

      • 感谢您的解释。我不明白为什么 PendingIntents 会被覆盖。难道不能安排两个在不同时间做同样事情的 PendingIntents 吗?
      • 还有一个问题:“......当手机唤醒时,它会重播过去排队的任何内容。在这种情况下,您的待处理意图将触发......” - 你呢?仅表示最后一个 PendingIntent?
      • 是的,如果闹钟在设备休眠时响起,AlarmManager 将在设备下次唤醒时发送 PendingIntent。
      • 在尝试将一堆我想在不同时间触发的事情排队时,我遇到了同样的挫败感。这就是我开始实现内部队列的原因。
      • 好吧,最后一件事 - 你能解释一下究竟什么是经常性警报,是它们没有不同的意图动作吗?也许这可以解决这个问题...... :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多