java - AlarmManager:如何安排每日闹钟和处理时间变化

标签 java android broadcastreceiver alarmmanager dst

我需要在每天的给定时间设置闹钟。我正在使用 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 事件,我该如何解决。
  • 这些 Intent 是否也会检测 DST 时间变化?
  • 如果不可能,是否有更好的方法在本地时间编程闹钟并处理时间变化?

提前致谢。

最佳答案

你应该使用

<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?

关于java - AlarmManager:如何安排每日闹钟和处理时间变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19421616/

相关文章:

c# - BroadcastReceiver 不接收广播

android - 如果应用程序尚未运行,广播接收器不会收到 ACTION_BOOT_COMPLETED?

java - 如何在图形中搜索路径?

java - 如何通过Java中的方法动态设置对象变量

android - 我的可扩展 ListView 不会展开

java - 如何解码AndroidManifest.xml

android - 如何通过 BroadcastReceiver 将应用程序从后台带到前台

java - ThreadPool 之于 Executor 就像轮询之于?

java - 如何在任务管理器中隐藏应用程序的预览

java - 单击 SwipeRefreshLayout 下的 RecyclerView 项目时,机器人测试中止