【问题标题】:Android repeat alarm manager in not triggering immediatelyAndroid重复警报管理器不会立即触发
【发布时间】:2015-01-04 14:52:36
【问题描述】:

我的代码:

Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.HOUR_OF_DAY, 11);
calSet.set(Calendar.MINUTE, 20);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);

PendingIntent pi=PendingIntent.getBroadcast(context,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,calSet.getTimeInMillis(),pi);

然后说,我在 11:30 执行。警报立即触发(这是预期的)。 但是,当我使用时也是一样的

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calSet.getTimeInMillis(),24*60*60*1000,pi);

警报不会立即触发。最多有 1 分钟的延迟(这是意料之外的)。 我希望重复警报立即触发,没有任何延迟。

有人可以帮我解决这个问题吗?

【问题讨论】:

  • WILD GUESS:您的目标是 API 级别 19+
  • @Der Golem minSdkVersion 11 targetSdkVersion 21
  • 你看到了吗?我是对的 - 这就是我使用 targetSdkVersion 18. 的原因
  • developer.android.com/reference/android/app/AlarmManager.html: Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use.
  • 不是每个人都会喜欢我的回答。许多人是时尚追随者,因此他们关注材料设计。如果发布这样的答案,我会冒很多反对票的风险。 @hqt 答案是正确的 (+1),因此您可以接受 他的 答案。

标签: android alarmmanager alarm android-alarms repeatingalarm


【解决方案1】:

您应该将代码更改为:

PendingIntent pi=PendingIntent.getBroadcast(context,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
      alarmManager.setExact(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
} else {
      alarmManager.set(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
}

@编辑 上面的代码将适用于设置准确的时间。但本节将解释有关警报管理器的重复。

对于低于 19 的 api,我们使用AlarmManager.setRepeating() 将定期在指定时间准确触发警报。但是从 19 和更高版本开始,此方法将不再起作用,并且没有任何 api 支持此行为。我认为这种 api 更改使开发人员在创建计时器时更加仔细地思考。因为定时定时触发会消耗大量电池电量。

如果你愿意,你必须自己做。首先,你设置AlarmManager.setExact(),当警报触发时,你会在下次再次触发警报手动

代码如下:

PendingIntent pi=PendingIntent.getBroadcast(context,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
     alarmManager. setExact(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
} else {
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
}

在您的意图中,您应该在放置句柄代码的地方检查 android api >= 19,应用程序将为下一个事件创建新警报。

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
         doSomething();
         // calculate time for next event
         Calendar nextEvent = calcNextEvent();
         // and set alarm again
         alarmManager. setExact(AlarmManager.RTC_WAKEUP, nextEvent.getTimeInMillis(), pi);
 } else {
         doSomething();
 }

我认为这是 android api 设计中的问题。旧代码应该适用于新版本。无论如何,这个新的 api 设计让开发人员的一切都变得更清晰,对系统更好(节省电池)。当然,当你使用新的 api 时 :)

希望有帮助:)

【讨论】:

  • 我猜,这不是重复警报。我正在寻找重复警报。
  • @Ravindra 我已经编辑了我的帖子。您可以再次看到 :) 基本上,从 API >= 19。您必须手动执行此操作
  • @hqt 我完全按照你在这里写的那样重复,我得到的问题是我的广播接收器在我的棒棒糖设备上被调用了大约 10-30 次(似乎是随机的)。它使用 setExact 来触发警报,当它触发时,它会再次执行 setExact(这应该在 1 天后发生,但它会立即被调用 10-30 次)。你知道可能是什么原因吗?你能帮我吗?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多