AlarmManager是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent,为你的应用设定一个在未来某个时间唤醒的功能。

当闹钟响起,实际上是系统发出了为这个闹钟注册的广播,会自动开启目标应用。

注册的闹钟在设备睡眠的时候仍然会保留,可以选择性地设置是否唤醒设备,但是当设备关机和重启后,闹钟将会被清除。

对于常规的短时间计时操作(ticks, timeouts, etc),使用Handler处理更加方便和有效率。

在alarm的receiver的onReceive()方法被执行的时候,AlarmManager持有一个CPU唤醒锁,这样就保证了设备在处理完广播之前不会sleep。一旦onReceive()方法返回,AlarmManager就会释放这个锁,表明一些情况下可能onReceive()方法一执行完设备就会sleep。如果你的alarmreceiver中调用了Context.startService(),那么很可能service还没起来设备就sleep了。为了阻止这种情况,你的BroadcastReceiver和Service需要实现不同的唤醒锁机制,来确保设备持续运行到service可用为止。

如果onReceive()方法里确实需要异步操作的话,可以用goAsync方法,然后在新开一个线程去执行。

如果onReceive()有过于耗时的操作,建议使用PendingIntent.getService()启动Service方式来完成。

BroadcastReceiver onReceive()使用goAsync 执行异步操作例子:

@Overridepublic void onReceive(final Context context, final Intent intent) {final PendingResult result = goAsync();final PowerManager.WakeLock wl = AlarmAlertWakeLock.createPartialWakeLock(context);try {wl.acquire();} catch (Exception e) {e.printStackTrace();}AsyncHandler.post(new Runnable() {@Overridepublic void run() {LogUtils.writeAlarmLog("AlarmStateManager received intent " + intent);try {handleIntent(context, intent);result.finish();wl.release();} catch (Exception e) {e.printStackTrace();}}});}

Alarm接口

1.cancel(PendingIntent operation)

Remove any alarms with a matching Intent.

2.changeAlarmType(String pkgName, boolean wakeup)

3.getNextAlarmClock()

Gets information about the next alarm clock currently scheduled.

4.set(int type, long triggerAtMillis, PendingIntent operation)

Schedule an alarm.

5.setAlarmClock(AlarmManager.AlarmClockInfo info, PendingIntent operation)

Schedule an alarm that represents an alarm clock.

6.setExact(int type, long triggerAtMillis, PendingIntent operation)

Schedule an alarm to be delivered precisely at the stated time.

7.setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour.

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

Schedule a repeating alarm.

9.setTime(long millis)

Set the system wall clock time.

10.setTimeZone(String timeZone)

Set the system default time zone.

11.setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation)

Schedule an alarm to be delivered within a given window of time.

常用接口

1.public void set/setExact(int type, long triggerAtMillis, PendingIntent operation)

该方法用于设置一次性闹钟。

第一个参数int type 指定定时服务的类型,该参数接受如下值:

ELAPSED_REALTIME: 在指定的延时过后,发送广播,但不唤醒设备(闹钟在睡眠状态下不可用)。如果在系统休眠时闹钟触发,它将不会被传递,直到下一次设备唤醒。

ELAPSED_REALTIME_WAKEUP: 在指定的延时过后,发送广播,并唤醒设备(即使关机也会执行operation所对应的组件)。延时是要把系统启动的时间SystemClock.elapsedRealtime()算进去的,具体用法看代码。

RTC: 指定当系统调用System.currentTimeMillis()方法返回的值与triggerAtTime相等时启动operation所对应的设备(在指定的时刻,发送广播,但不唤醒设备)。如果在系统休眠时闹钟触发,它将不会被传递,直到下一次设备唤醒(闹钟在睡眠状态下不可用)。

RTC_WAKEUP: 指定当系统调用System.currentTimeMillis()方法返回的值与triggerAtTime相等时启动operation所对应的设备(在指定的时刻,发送广播,并唤醒设备)。即使系统关机也会执行 operation所对应的组件。

第二个参数triggerAtMillis表示触发闹钟的时间。

第三个参数PendingIntent pi表示闹钟响应动作:

PendingIntent pi:是闹钟的执行动作,比如发送一个广播、给出提示等等。PendingIntent是Intent的封装类。需要注意的是:

启动服务:如果是通过启动服务来实现闹钟提示的话,PendingIntent对象的获取就应该采用Pending.getService(Context c,int i,Intent intent,int j)方法;

启动广播:如果是通过广播来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getBroadcast(Context c,inti,Intent intent,int j)方法;

启动activity:如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getActivity(Context c,inti,Intent intent,int j)方法。

如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。

注意:AndroidL开始,设置的alarm的触发时间必须大于当前时间 5秒

AlarmManagerService中是通过PendingItent来标示一个Alarm的

2.public void cancel (PendingIntent operation)

移除intent相匹配的alarm(只要action,data, type,package,component,categories相等,就会被取消)。另外,应用被forcestoppackage杀掉之后,所有的alarm都会被移除。

3.public void setRepeating(int type,long startTime,long intervalTime,PendingIntent pi)

设置一个周期性执行的定时服务。第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。

注意:该方法提供了设置周期闹钟的入口,闹钟执行时间严格按照startTime来处理,使用该方法需要的资源更多,不建议使用。

4.public void setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi)

该方法也用于设置重复闹钟,与第二个方法相似,不过其两个闹钟执行的间隔时间不是固定的而已。它相对而言更省电(power-efficient)一些,因为系统可能会将几个差不多的闹钟合并为一个来执行,减少设备的唤醒次数。第三个参数intervalTime为闹钟间隔,内置的几个变量如下:

INTERVAL_DAY: 设置闹钟,间隔一天

INTERVAL_HALF_DAY: 设置闹钟,间隔半天

INTERVAL_FIFTEEN_MINUTES:设置闹钟,间隔15分钟

INTERVAL_HALF_HOUR: 设置闹钟,间隔半个小时

INTERVAL_HOUR: 设置闹钟,间隔一个小时

AndroidL开始repeat的周期必须大于60秒

设置一个闹钟和取消一个闹钟的例子:

private static class AlarmManagerStateChangeScheduler implements StateChangeScheduler {@Overridepublic void scheduleInstanceStateChange(Context context, Calendar time,AlarmInstance instance, int newState) {long timeInMillis = time.getTimeInMillis();Intent stateChangeIntent = createStateChangeIntent(context, ALARM_MANAGER_TAG, instance,newState, VALUE_CHANGE_STATE_BY_SCHEDULE);// Treat alarm state change as high priority, use foreground broadcastsstateChangeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);PendingIntent pendingIntent = PendingIntent.getService(context, instance.hashCode(),stateChangeIntent, PendingIntent.FLAG_UPDATE_CURRENT);//设置一个闹钟AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);if (CommonUtils.isMOrLater()) {am.setExactAndAllowWhileIdle(ReflectUtils.getRTC_BOOT_WAKEUP()/*AlarmManager.RTC_WAKEUP*/, timeInMillis, pendingIntent);LogUtils.writeAlarmLog("Scheduling state change success by setExactAndAllowWhileIdle");} else if (CommonUtils.isKitKatOrLater()) {am.setExact(ReflectUtils.getRTC_BOOT_WAKEUP()/*AlarmManager.RTC_WAKEUP*/, timeInMillis, pendingIntent);LogUtils.writeAlarmLog("Scheduling state change success by setExact");} else {am.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);LogUtils.writeAlarmLog("Scheduling state change success not KitKatOrLater");}}@Overridepublic void cancelScheduledInstanceStateChange(Context context, AlarmInstance instance) {LogUtils.writeAlarmLog("cancelScheduledInstance instance id = " + instance.mId);// Create a PendingIntent that will match any one set for this instancePendingIntent pendingIntent = PendingIntent.getService(context, instance.hashCode(),createStateChangeIntent(context, ALARM_MANAGER_TAG, instance, null, null),PendingIntent.FLAG_NO_CREATE);//取消一个闹钟if (pendingIntent != null) {AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);am.cancel(pendingIntent);pendingIntent.cancel();ReflectUtils.cancelOnePoweroffAlarm(am, pendingIntent);}}}

AlarmManager使用相关推荐

  1. Android 轮询最佳实践 Service + AlarmManager+Thread

    为什么80%的码农都做不了架构师?>>>    android中涉及到将服务器中数据变化信息通知用户一般有两种办法,推送和轮询. 消息推送是服务端主动发消息给客户端,因为第一时间知道 ...

  2. Android中的定时器AlarmManager

    AlarmManager的常用方法有三个: (1)set(int type,long startTime,PendingIntent pi):         该方法用于设置一次性闹钟,第一个参数表示 ...

  3. AlarmManager与PendingIntent的联合使用(二)

    PendingIntent.getService配合AlarmManager,自定义个类继承Service: package com.example.alarmmanager;import andro ...

  4. AlarmManager与PendingIntent的联合使用(一)

    AlarmManager与PendingInteng.getBroadcast及getActivity: package com.example.alarmmanager;import android ...

  5. 我的Android进阶之旅------gt;Android使用AlarmManager全局定时器实现定时更换壁纸

    该DEMO将会通过AlarmManager来周期的调用ChangeService,从而让系统实现定时更换壁纸的功能. 更换壁纸的API为android.app.WallpaperManager,它提供 ...

  6. 【Android 电量优化】电量优化 ( 使用 AlarmManager 保持 CPU 唤醒 )

    文章目录 一.AlarmManager 简介 二.使用 AlarmManager 保持 CPU 唤醒流程 ( 省电操作 ) 三.使用 WeakLock 保持 CPU 唤醒 代码示例 1.Service ...

  7. AlarmManager深入浅出

    原文链接:侯 亮,https://my.oschina.net/youranhongcha/blog/149564 1.概述 在Android系统中,闹钟和唤醒功能都是由Alarm Manager S ...

  8. android:catation=quot;90quot;,Android中的AlarmManager的使用.htm

    var protocol = window.location.protocol; document.write(' Android中的AlarmManager的使用 - wangxingwu_314的 ...

  9. android小部件如何实时更新,android – 使用AlarmManager手动更新小部件

    如 Android Dev Guide中所述,如果您希望窗口小部件更频繁地更新,则应使用AlarmManager设置不唤醒设备的警报. 原则上:不要使用AppWidgetProvider类提供的标准机 ...

  10. Android中使用AlarmManager设置闹钟

    场景 设置闹钟 闹钟提醒 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新 ...

最新文章

  1. react开发心路历程
  2. SpringBoot框架:入门篇
  3. glide_在Android中将数据绑定与Glide结合使用
  4. keepalived 主从配置日志报错:one or more vip associated with vrid mismatch actual master advert...
  5. 信息安全系统设计基础第九周总结
  6. poj 1149 PIGS【最大流】
  7. android透明像素效率,android-非透明像素上的ImageView ColorFilter.夹
  8. 使用hessian+protocol buffer+easyUI综合案例--登陆
  9. 汤家凤:历年真题怎么用?接力题典怎么配合?黄金十月拼命干,提高很多分数不是梦!...
  10. 【MATLAB】图像分割
  11. 机器学习之---马尔可夫随机场的应用
  12. esxi能直通的显卡型号_显卡参数看不懂?手把手教你选独立显卡
  13. 根据两个字段去重SQL语句
  14. 【律联云知产课堂】商标注册需要什么条件?
  15. JS逆向 | 面向小白之eval混淆
  16. “毕竟,你胜利了......敬胜利者一杯。”
  17. win10系统找不到telnet服务器,win10系统找不到Telnet服务的解决教程
  18. 解决微信“聊天界面中的新消息通知”设置按钮不见了问题
  19. Cadence Allegro PCB设计88问解析(二) 之 Allegro中Artwork层复用(导入导出)
  20. 2022年03月05日:宜未雨而绸缪,毋临渴而掘井

热门文章

  1. Android studio 运行即打包keystore之build.gradle设置
  2. mpvue 从零开始 女友的发带 2 window中设置
  3. 织梦DEDECMS网站留言板提交时验证码错误返回空白页的解决办法
  4. 申请鲲鹏920测试机试水+编译nginx
  5. ie9支持string.trim()
  6. 计算机应用基础专科作业二,电子科大18秋《计算机应用基础(专科)》在线作业2...
  7. java文件替换一行数据_用Golang替换文件中的一行
  8. html菜鸟ruby,Ruby 循环
  9. just for rest~
  10. mybatis TypeHandler 类型处理器