Android中的定时器AlarmManager

来源:互联网 发布:哪个软件听音乐最好 编辑:程序博客网 时间:2024/06/09 17:34

AlarmManager的常用方法有三个:
(1)set(int type,long startTime,PendingIntent pi);
        该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。
(2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
        该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第四个参数表示闹钟响应动作。类似JAVA的Timer里面scheduleAtFixedRate(TimerTask task, long delay, long period),时间间隔相对比较精确,在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。在长期运行中,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
(3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
        该方法也用于设置重复闹钟,与第二个方法相似,不过其两个闹钟执行的间隔时间不是固定的而已。类似JAVA的Timer里面schedule(TimerTask task, Date firstTime, long period),以近似固定的时间间隔(由指定的周期分隔)进行后续执行。在固定速率执行中,根据已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”。从长远来看,执行的频率将正好是指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
 
三个方法各个参数:
(1)int type:闹钟的类型,常用的有5个值: 
[java] 
AlarmManager.ELAPSED_REALTIME 
AlarmManager.ELAPSED_REALTIME_WAKEUP 
AlarmManager.RTC 
AlarmManager.RTC_WAKEUP 
AlarmManager.POWER_OFF_WAKEUP 

        AlarmManager.ELAPSED_REALTIME表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
        AlarmManager.ELAPSED_REALTIME_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
        AlarmManager.RTC表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
        AlarmManager.RTC_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
        AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;

(2)long startTime:
        闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。需要注意的是,本属性与第一个属性(type)密切相关,
        如果第一个参数对应的闹钟使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间(相对于系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime();
        如果第一个参数对应的闹钟使用的是绝对时间(RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间就表示为:System.currentTimeMillis()。

(3)long intervalTime:
        对于后两个方法来说,存在本属性,表示两次闹钟执行的间隔时间,也是以毫秒为单位。

(4)PendingIntent pi:
        是闹钟的执行动作,比如发送一个广播、给出提示等等。PendingIntent是Intent的封装类。需要注意的是,如果是通过启动服务来实现闹钟提示的话,PendingIntent对象的获取就应该采用Pending.getService(Context c,int i,Intent intent,int j)方法;如果是通过广播来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getBroadcast(Context c,int i,Intent intent,int j)方法;如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。
 
AlarmManager使用示例:利用用户自定义广播实现闹钟功能,从当前时间开始,每隔10分钟提示一次
(1)实现原理:在SendActivity.java中定义一个AlarmManager对象,指定该对象从当前时间开始,每隔10分钟向名为“MYALARMRECEIVER”的广播接收器发出一条广播,附加消息内容为“你该打酱油了”;创建一个名为MyReceiver的广播接收器,在其onReceive方法中获取Intent对象传过来的值(“你该打酱油了”)并用一个Toast组件显示出来;在AndroidManifest.xml文件中注册SendActivity类和广播接收器类MyReceiver,设置MyReceiver的action的值为“MYALARMRECEIVER”
(2)代码实现:
创建广播接收类MyReceiver.java,在其onReceive方法中获取Intent的附加信息msg,并用Toast组件显示
[java] view plaincopyprint?
public void onReceive(Context context,Intent intent){ 
     String msg = intent.getStringExtra("msg"); 
     Toast.makeText(context,msg,Toast.LENGTH_SHORT).show(); 

创建SendActivity.java,用于设置闹钟,定时发出广播
[java] 
//创建Intent对象,action指向广播接收类,附加信息为字符串“你该打酱油了” 
 
Intent intent = new Intent("MYALARMRECEIVER"); 
 
intent.putExtra("msg","你该打酱油了"); 
 
//创建PendingIntent对象封装Intent,由于是使用广播,注意使用getBroadcast方法 
 
PendingIntent pi = PendingIntent.getBroadcast(this,0,intent,0); 
 
//获取AlarmManager对象 
 
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); 
 
//设置闹钟从当前时间开始,每隔10分钟执行一次PendingIntent对象,注意第一个参数与第二个参数的关系 
 
am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentMillis(),600*1000,pi); 

有时候,也许我们需要同时开启多个定时器,我们先来看看下面这段代码:
[java]
AlarmManager am = null; 
am = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
for (int i = 0; i < 10; i ++) { 
    ... 
    Intent i = new Intent("xxx"); 
    PendingIntent sender = PendingIntent.getBroadcast(context.getApplicationContext(), 0, i, PendingIntent.FLAG_UPDATE_CURRENT); 
    ... 
    am.setRepeating(...); 

如果采用这种做法后面的定时器会将前面的定时器"覆盖"掉,只会启动最后一个定时器
解决办法
PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags);
第二个参数requestCode一定要是唯一的,比如不同的ID之类的,(如果系统需要多个定时器的话)。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 皮肤藓是怎么引起的 脸部疱疹怎么引起的 脑膜瘤是怎么引起的 阴毛囊炎怎么引起的 脚痛风是怎么引起的 寻常疣是什么引起的 脂肪瘤是怎么引起的 脑垂体瘤是什么引起的 腰痛是什么原因引起的 坐骨神经痛怎么引起的 传染性软疣怎么引起的 左背痛是什么原因引起的 脑供血不足是怎么引起的 手臂发麻是什么原因引起的 小腿浮肿是什么原因引起的 腰椎管狭窄怎么引起的 脚后跟疼是什么原因引起的 腿痛有哪些原因引起 末梢神经炎怎么引起的 腿浮肿是什么原因引起的 血糖高是什么原因引起的 腰椎滑脱是什么引起的 坐骨神经痛是怎么引起的 肾功能不全怎么引起的 腰困是什么原因引起的 腰肌劳损是怎么引起的 泡疹是什么原因引起的 嘴唇疱疹是怎么引起的 肾功能衰竭是怎么引起的 带状疱疹是什么引起 坐骨神经痛是怎样引起的 病毒性软疣怎么引起的 坐骨神经疼是什么引起的 坐骨神经是怎么引起的 腰椎管狭窄是什么引起的 病毒性疱疹怎么引起的 衣原体感染怎么引起的 颈椎痛是什么原因引起的 腰部带状疱疹是怎么引起的 妇科囊肿是什么引起的 胆囊息肉是什么引起的