【问题标题】:AlarmManager: how to schedule a daily alarm and deal with time changesAlarmManager:如何安排每日闹钟并处理时间变化
【发布时间】:2013-10-25 15:24:09
【问题描述】:

我需要在每天的特定时间设置闹钟。我正在使用AlarmManager.RTC_WAKEUP 对警报进行编程,因此它使用系统时间作为参考。我将闹钟设置为在所需时间首先执行,然后每天重复:

    alarmManager.setRepeating(
        AlarmManager.RTC_WAKEUP,
        getTimestampToday("12:00"),
        AlarmManager.INTERVAL_DAY,
        pendingIntent
    );

getTimestampToday 方法在所需时间返回今天的长时间戳。它通过获取今天的本地日期,然后设置所需的时间,最后将其转换回时间戳(基于 UTC)来实现。

这里的问题是警报应该按照当地时间工作。因此,如果在安排闹钟后时间更改(例如,DST 时间更改,或者用户去了不同的国家,或者他手动更改了日期、时间或时区),那么闹钟将在错误的当地时间触发下一次。

例子:

  1. 警报设置为在上午 8:00 首次触发,每天重复(意味着 86400 秒的间隔)。
  2. 当晚,在凌晨 3:00 自动更改 DST 时间,将时钟拨回凌晨 2:00。
  3. 第二天早上,闹钟在早上 7:00 响起,这是错误的。

该应用程序旨在长时间运行(它是一个仅供企业使用的信息亭应用程序)。我正在重新安排应用程序启动时的警报,但这并不能解决我的问题,因为该应用程序可以运行数天而无需重新启动。我需要检测时间何时更改以根据新的本地时间再次安排闹钟。

我正在使用这个接收器:

    <receiver android:name="foo.bar.receivers.TimeChangeReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.ACTION_TIMEZONE_CHANGED" />
            <action android:name="android.intent.action.ACTION_TIME_CHANGED" />
            <action android:name="android.intent.action.DATE_CHANGED"></action>
        </intent-filter>
    </receiver>

它检测日期更改,但不适用于时间更改或时区更改。 (在运行 OS 4.0.3 的平板电脑上进行了测试)。真的很奇怪,因为我可以清楚地看到在 logcat 中广播的事件。

所以我的问题:

  • 为什么我的 BroadcastReceiver 没有接收到 ACTION_TIMEZONE_CHANGEDACTION_TIME_CHANGED 事件,我该如何解决。
  • 这些意图是否也会检测 DST 时间变化?
  • 如果不可能,是否有更好的方法来设置当地时间的警报并处理时间变化?

提前致谢。

【问题讨论】:

  • 好问题。我正在使用 ACTION_TIME_CHANGED ,遗憾的是,当用户更改它时,不仅调用它,而且在 1 小时内调用了大约 2-3 次。我不知道如何处理那些垃圾邮件回调
  • @matheszabi 也许设备实际上每小时与时间服务器同步 2-3 次?
  • 非常好的问题,+1。希望有人对此有一个好的答案!
  • @MisterSmith 我认为android:exported="true" 可以完成这项任务。将此添加到接收器..
  • 是的,你是对的。您尝试过android.intent.action.TIME_SET 操作吗?

标签: java android broadcastreceiver alarmmanager dst


【解决方案1】:

你应该使用

<action android:name="android.intent.action.TIMEZONE_CHANGED" /> 
<action android:name="android.intent.action.TIME_SET" />

代替

  <action android:name="android.intent.action.ACTION_TIMEZONE_CHANGED" />
  <action android:name="android.intent.action.ACTION_TIME_CHANGED" />

请参阅 ACTION_TIMEZONE_CHANGEDACTION_TIME_CHANGED。并观察为这些常量提供的值。


对于 DST 更改,请阅读 Does Android AlarmManager handle daylight saving changes?

【讨论】:

  • 谢谢。你知道这是否也会检测到 DST 转换?
  • 嘿 DST 更改将由 AlarmManager 本身处理。阅读更多stackoverflow.com/questions/8377853/…
  • 我不这么认为,但我不能花更多时间来测试这个。顺便说一句,刚刚完成了一个测试(我花了 1 个小时来测试 DST)并且这些事件没有被触发。看起来他们只检测用户发起的时间变化。我现在正在做的是在周日凌晨 4:30 重新安排所有警报(这里的 DST 更改总是在周日,并且总是在 2:00-3:00 的时间间隔内。这也应该有助于网络时间同步一周。
  • BroadcastReceiver onReceive 在手动更改日期或时间时调用了多次,在清单中我使用这两个作为意图过滤器 TIME_SET 和 DATE_CHANGED
猜你喜欢
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
相关资源
最近更新 更多