Alarm

来源:互联网 发布:高铁管家抢票软件 编辑:程序博客网 时间:2024/05/17 08:20

android的alarm机制可以让你在app的生命周期之外做一些基于时间的操作,例如周期性的更新mail,天气信息等等。

实作的时候一般是通过alarm manager在具体的时间点或者某一个时间间隔发出intent或者broadcast,另一侧在receiver中执行相关的操作。

创建alarm

在创建alarm的时候需要确定alarm的类型,alarm的时间或者时间间隔(如果你指定的时间已经过去,那么alarm会立刻被触发),到达某个时间时发出什么样的Pending Intent。


alarm有两大类,一是elapsed real time,这个是相对于系统启动时间的时间,二是real time clock(RTC),这是绝对时间。前者适用于隔一段时间执行某个任务,后者适用于在一天中的某个时间执行一个任务。

然后每一类alarm还有一个wake版本,意思是即便当时屏幕是熄灭状态也会唤醒CPU,如果你使用非wake版本就不会唤醒CPU,相应的操作在下次点亮屏幕时才会执行。所以如果对时间要求比较严格需要使用wake版本。

所以总计四种类型:

ELAPSED_REALTIME—Fires the pending intent based on the amount of time since the device was booted, but doesn't wake up the device. The elapsed time includes any time during which the device was asleep.
ELAPSED_REALTIME_WAKEUP—Wakes up the device and fires the pending intent after the specified length of time has elapsed since device boot.
RTC—Fires the pending intent at the specified time but does not wake up the device.
RTC_WAKEUP—Wakes up the device to fire the pending intent at the specified time.

30分钟后启动隔30分钟再启动

alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        AlarmManager.INTERVAL_HALF_HOUR,    //30mins后执行
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);  //间隔30mins执行

一分钟后,只启动一次

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);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,    //启动一次使用set而不是setRepeat
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);



alarm的精度:

使用setInexactRepeating会把近似时间的alarm一起触发,这样节省电量;使用setRepeating比较精确。


Cancel alarm

呼叫alarm manager的cancel方法,入参是之前的pending intent。

if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}




在设备启动时创建一个alarm

设备关机时会自动cancel alarm,你可以在设备重启后自动开启alarm。

1,首先要声明权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
2,实现receiver,重新设置alarm

3,在manifest中声明receiver

<receiver android:name=".SampleBootReceiver"
        android:enabled="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"></action>
    </intent-filter>
</receiver>

enable属性设置为false,意思是必须在程序中手动enable这个receiver它才会收到broadcast,

在程序中enable/disable可以overridemanifest中的值。

ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();


pm.setComponentEnabledSetting(receiver,
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(receiver,
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);