Android 使用 AlarmManager 每天在同一时间设置重复任务

Android set repeating task at same time everyday using AlarmManager

必须在每天晚上 8 点(时钟显示晚上 8 点)安排一个事件,无论用户在不同时区移动。设置以一天为间隔重复将不会在正确的时间发送。如何解决这个问题?

This 是我目前最接近的。

代码片段:

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 20:00 PM
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 0);

// setRepeating() lets you specify a precise custom interval--in this case,
// 1 day
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

要考虑 TimeZone 更改,您需要注册一个 TIMEZONE_CHANGED 广播接收器:

<receiver android:name=".TimeZoneBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.TIMEZONE_CHANGED " />
    </intent-filter>
</receiver>

我会保存当前的 TimeZone,然后在下次警报发生时检索它,这样我们就可以仔细检查是否发生了任何更改,因此 java 代码将类似于:

public class TimeZoneBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
        String timeZoneOLD = pref.getString(PREF_TIMEZONE, null);
        String timeZoneNEW = TimeZone.getDefault().getID();   
        long now = System.currentTimeMillis();

        if (timeZoneOLD == null || TimeZone.getTimeZone(timeZoneOLD).getOffset(now) != TimeZone.getTimeZone(timeZoneNEW).getOffset(now)) {
                pref.edit().putString(PREF_TIMEZONE, timeZoneNEW).commit();
                // This means that the TimeZone has changed so we need to update the alarm
                // Set Alarm method goes HERE ...
    }

}

有关如何使用警报管理器设置重复任务的更多信息,以下是一个很好的教程: