AlarmManager 警报在错误的时间响起

AlarmManager alarm goes off at the wrong time

我正在尝试使用 AlarmManager 创建示例警报应用程序。但是,即使我设置了特定的触发时间,闹钟也会在不同的时间响起。

设置闹钟:

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 18); // trigger at 6 PM

        Intent notifyIntent = new Intent(context, CheckupAlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast
                (context, 100, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        android.app.AlarmManager alarmManager = (android.app.AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (alarmManager != null) {
            alarmManager.setInexactRepeating(android.app.AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                    android.app.AlarmManager.INTERVAL_DAY, pendingIntent);
        }

清单:

<receiver
      android:name=".notifications.CheckupAlarmReceiver"
      android:enabled="true"
      android:exported="false" />

重申一下,警报正常。它只是在错误的时间触发。 Calendar 实例是否没有考虑时区?我在这里做错了什么?

您正在设置 setInexactRepeating(),正如其名称所示,它无法在您指定的确切时间触发。这是一项优化,因此操作系统会尝试获取多个应该在相似时间触发的警报,以便同时触发所有警报。

相反,您可以使用 void setExactAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation)。参见 documentation

示例:

 alarmManager.setExactAndAllowWhileIdle(android.app.AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

根据其建议,您不应使用具有确切时间的重复闹钟。相反,您可以等到确切的警报响起,然后在第二天安排另一个警报。

小于23的API可以使用void setExact(int type, long triggerAtMillis, PendingIntent operation)。对于低于 19 的 API,您可以像往常一样使用 void setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation) 和预期的精确触发。