关于AlarmManager你必须知道的事!

AlarmManager简介

官方简介

AlarmManager提供对系统警报服务的访问。这些允许您在将来的某个时间点运行应用程序。当警报响起时,系统会广播已注册的意图,如果目标应用程序尚未运行,则自动启动它。当设备处于休眠状态时,会保留已注册的警报(如果设备在此期间发生故障,可以选择将其唤醒),但如果设备被关闭并重新启动,则会清除该警报。警报管理器持有一个CPU唤醒锁,只要警报接收器的onReceive()方法正在执行。这保证了在你处理完广播后,手机才会休眠。一旦onReceive()返回,警报管理器将释放此唤醒锁。这意味着,在某些情况下,只要onReceive()方法完成,手机就会休眠。如果您的警报接收器调用Context.startService(),那么在启动所请求的服务之前,手机可能会休眠。为了防止这种情况发生,您的BroadcastReceiver和Service将需要实现一个单独的唤醒锁定策略,以确保在服务可用之前继续运行电话。

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(吐槽下华为手机变态的省电机制)基本上想要使用准确的系统警报的话是比较有难度的。当然保活成功的话也是可以使用的。

1.常量

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版本影响,某些版本并不支持;

2.常用的方法

①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以后的系统上谷歌官方推荐的方法是重复的使用一次性的闹铃来达到重复的作用。

仅供参考,如有错误,欢迎指正谢谢!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值