Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
You do not instantiate this class directly; instead, retrieve it through Context.getSystemService(Context.ALARM_SERVICE).
以上红色字体的大致意思就是从api19(巧克力)开始警报开始变得不准确,意思就是说在android4.4以前的手机上报时仍然准确,但是在4.4以后的手机上是不准确,但是如果你一定要使用准确的系统警报是建议调用setWindow()和setExact()方法.但是但是但是重点!!重点!!就是以国内目前的情形各个ROM厂商对系统的各种biubiubiubiu(吐槽下华为手机变态的省电机制)基本上想要使用准确的系统警报的话是比较有难度的。当然保活成功的话也是可以使用的。
AlarmManager主要是使用到了5个关于时间类型的常量
ELAPSED_REALTIME:表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3,使用SystemClock.elapsedRealtime()可获得时间
ELAPSED_REALTIME_WAKEUP:表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2,SystemClock.elapsedRealtime();
RTC:表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间( SystemClock.currentThreadTimeMillis()),即当前系统时间,状态值为1;
RTC_WAKEUP:表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间(SystemClock.currentThreadTimeMillis()),状态值为0;
AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;
①set(int type, long triggerAtMillis, PendingIntent operation)
该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。
②setExact(int type, long triggerAtMillis, PendingIntent operation)
设置一个闹钟在规定的时间内准确地发出。(当然准确是不可能准确的)
③ setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation)
大致的参数同前面几个,第三个参数指的是当警报发出时最大延迟时间是多少。
④setExactAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation)
同setExact,即使在系统低功耗的情况下也能发出警报,
⑤setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation)
同set咯
⑥setAlarmClock(AlarmManager.AlarmClockInfo info, PendingIntent operation)
第一个参数表示闹钟的信息当然使用的是绝对时间,第二参数想要执行的意图
由于我的需求是需要app在熄屏以后也能继续运行所以很是尴尬在保活成功的前提下我使用了如下方法:
//7.0以上的手机
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
AlarmManager.AlarmClockInfo alarmClockInfo = newAlarmManager.AlarmClockInfo(targetTime, null);
mAlarmManager.setAlarmClock(alarmClockInfo, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//android 6.0以上7.0一下的手机
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, targetTime, pendingIntent);
} else {
mAlarmManager.set(AlarmManager.RTC_WAKEUP, targetTime, pendingIntent);
}
亲测在小米手机上延迟小于60S 但是在华为7.0的手机上无效仍然存在问题 在华为8.0的手机上没有问题。
关于设置重复闹铃的问题情况:
setInexactRepeating (int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
设置一个不精确的重复的闹钟
setRepeating (int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
设置一个精确的重复的闹钟(当然仅仅在api19之前是精确)
在4.4以后的系统上谷歌官方推荐的方法是重复的使用一次性的闹铃来达到重复的作用。
仅供参考,如有错误,欢迎指正谢谢!