AlarmManager:如何安排每日警报并处理时间变化

Mis*_*ith 11 java android broadcastreceiver dst alarmmanager

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

    alarmManager.setRepeating(
        AlarmManager.RTC_WAKEUP,
        getTimestampToday("12:00"),
        AlarmManager.INTERVAL_DAY,
        pendingIntent
    );
Run Code Online (Sandbox Code Playgroud)

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

这里的问题是警报应该根据当地时间工作.因此,如果在安排警报后更改时间(例如,DST时间更改,或者用户前往其他国家/地区,或者他手动更改日期,时间或时区),则警报将在错误的当地时间触发下次.

例:

  1. 警报设置为在上午8:00首先触发,每天重复(意味着间隔86400秒).
  2. 那天晚上,自动DST时间变化发生在凌晨3点,将时钟倒回到凌晨2点.
  3. 第二天早上,闹钟在早上7点开火,这是错误的.

该应用程序应该运行很长一段时间(它是一个仅供企业使用的自助服务终端应用程序).我在应用程序启动时重新安排警报,但这并不能解决我的问题,因为应用程序可以运行数天而无需重新启动.我需要检测时间的变化,以便根据新的本地时间再次安排警报.

我正在使用这个接收器:

    <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>
Run Code Online (Sandbox Code Playgroud)

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

所以我的问题:

  • 为什么我的BroadcastReceiver没有收到ACTION_TIMEZONE_CHANGEDACTION_TIME_CHANGED事件,我怎么能解决它.
  • 这些意图会检测到DST时间变化吗?
  • 如果不可能,是否有更好的方法在当地时间编程报警并处理时间变化?

提前致谢.

Pan*_*mar 8

你应该用

<action android:name="android.intent.action.TIMEZONE_CHANGED" /> 
<action android:name="android.intent.action.TIME_SET" />
Run Code Online (Sandbox Code Playgroud)

代替

  <action android:name="android.intent.action.ACTION_TIMEZONE_CHANGED" />
  <action android:name="android.intent.action.ACTION_TIME_CHANGED" />
Run Code Online (Sandbox Code Playgroud)

请参阅ACTION_TIMEZONE_CHANGEDACTION_TIME_CHANGED.并观察这些常数给出的值.


对于DST更改,读取Android AlarmManager是否可以处理夏令时更改?