Android系统服务-AlarmManager

/ 0评 / 0

前言

我们在应用开发的过程中常常需要使用定时操作,如果是短时间的比如几秒,几分的,我们可以使用的方法就有很多了,比如Thread,Timer,Handler等等,可是如果是闹钟应用呢,需要在几小时甚至几天以后进行操作,那前面提到的方法就不适用了,这种时候我们需要使用系统服务AlarmManager来实现了。

使用

创建AlarmManager

和使用其他系统服务一样:

AlarmManager mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

闹钟类型

休眠状态:屏幕不亮(按下电源键)

相对开机时间:手机开机到现在的时间(手机关于里面的已开机时间)

绝对时间:手机的时间(手机的当前时间)

测试结果:如果使用休眠状态不可用的类型,当闹钟时间到的时候,不会执行操作,会一直延迟,直到手机屏幕点亮(解除休眠状态)的一瞬间发出。非定时闹钟事件发出的最短间隔为5秒(小米 Android6.0测试)

上文中一直提到了相对时间,如何相对当前时间?举个栗子

Intent intent = new Intent();
intent.putExtra("extras", "hello");
intent.setAction("action");
PendingIntent broadcast = PendingIntent.getBroadcast(this, 11, intent, 0);
// 最低间隔5秒
mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 5000, broadcast);

我们可以使用SystemClock.elapsedRealtime()获取到系统的开机时间,然后在这个基础上加上我们需要的时间即可。

常用方法

设置一次性闹钟

方法一

int type 闹钟类型
long triggerAtTime 触发时间(毫秒为单位)
PendingIntent operation 触发的动作
mAlarmManager.set(int type, long triggerAtTime, PendingIntent operation)

方法二:参数含义与方法一相同,不过在targetSdkVersion >= 19时推荐使用方法二,原因在下文提到

setExact(int type, long triggerAtMillis, PendingIntent operation)

设置重复闹钟

方法一

int type 闹钟类型
long triggerAtTime 触发时间(毫秒为单位)
PendingIntent operation 触发的动作
long intervalMillis 两次触发的间隔(毫秒为单位)
setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

方法二:参数含义与方法一相同,不过在targetSdkVersion >= 19时推荐使用方法二,原因在下文提到

setRepeating(int type, long triggerAtMillis,long intervalMillis, PendingIntent operation)

重复闹钟有一个最短发出时间间隔,在小米3 Android6.0上测试为1分钟,根据官方文档,可被精确识别的常量如下

/**
 * Available inexact recurrence intervals recognized by
 */
public static final long INTERVAL_FIFTEEN_MINUTES = 15 * 60 * 1000;
public static final long INTERVAL_HALF_HOUR = 2*INTERVAL_FIFTEEN_MINUTES;
public static final long INTERVAL_HOUR = 2*INTERVAL_HALF_HOUR;
public static final long INTERVAL_HALF_DAY = 12*INTERVAL_HOUR;
public static final long INTERVAL_DAY = 2*INTERVAL_HALF_DAY;

为什么在在targetSdkVersion >= 19时推荐使用方法二?

根据官方文档:系统为了省电,在targetSdkVersion >= 19时,使用方法一可能将几个间隔时间差不多的闹钟事件和为一个发出。

取消重复闹钟

取消重复闹钟只需要调用如下方法,传入的参数为匹配的PendingIntent。

public void cancel(PendingIntent operation)

PendingIntent的匹配规则

PendingIntent的匹配规则为:如果两个PendingIntent它们内部的Intent相同并且requestCode也相同,那么这两个PendingIntent就是匹配的,requestCode比较好理解,Intent的匹配规则是:如果两个Intent的ComponentName和Intent-filter都相同,那么这两个Intent也就是相同的,需要注意的是,Extras不参与Intent是否匹配的比较

参考链接:许宏川的简书editor1994的博客

发表评论

您的电子邮箱地址不会被公开。