深入学习android之AlarmManager

时间:2022-12-26 10:56:11

http://jinguo.iteye.com/blog/799778

3个接口:

view plain copy to clipboard print ?
  1. // 取消已经注册的与参数匹配的闹铃    
  2. void    cancel(PendingIntent operation)  
  3. //注册一个新的闹铃   
  4. void    set( int  type,  long  triggerAtTime, PendingIntent operation)  
  5. //注册一个重复类型的闹铃   
  6. //triggerAtTime响铃时间,interval 响铃间隔
  7. void    setRepeating( int  type,  long  triggerAtTime,  long  interval, PendingIntent operation)  
  8. //设置时区   
  9. void    setTimeZone(String timeZone)  

setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi); 
该方法也用于设置重复闹钟,与第二个方法相似,不过其两个闹钟执行的间隔时间不是固定的而已。它相对而言更节能(power-efficient)一些,因为系统可能会将几个差不多的闹钟合并为一个来执行,减少设备的唤醒次数。 有点类似JAVA的Timer里面schedule(TimerTask task, Date firstTime, long period):根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。在长期运行中,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。

cancel(PendingIntent operation)
取消一个设置的闹钟



5个闹铃类型

view plain copy to clipboard print ?
  1. public   static   final   int  ELAPSED_REALTIME  
  2. // 当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,
  3. 该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时间,
  4. 可以通过调用SystemClock.elapsedRealtime()获得。系统值是3    (0x00000003)。   
  5.  public   static   final   int  ELAPSED_REALTIME_WAKEUP  
  6. //能唤醒系统,用法同ELAPSED_REALTIME,系统值是2 (0x00000002) 。   
  7.  public   static   final   int  RTC  
  8.  //当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,
  9. 该闹铃所用的时间是绝对时间,所用时间是UTC时间,
  10. 可以通过调用 System.currentTimeMillis()获得。系统值是1 (0x00000001) 。   
  11. public   static   final   int  RTC_WAKEUP  
  12. //能唤醒系统,用法同RTC类型,系统值为 0 (0x00000000) 。   
  13. Public static   final   int  POWER_OFF_WAKEUP  
  14. //能唤醒系统,它是一种关机闹铃,就是说设备在关机状态下也可以唤醒系统,所以我们把它称之为关机闹铃。
  15. 使用方法同RTC类型,系统值为4(0x00000004)。     


注意一个重要的参数PendingIntent。这个PendingIntent可以说是 Intent的进一步封装,

他既包含了Intent的描述又是Intent行为的执行(这种定义也许不太严格),

如果将Intent比作成一个订单的 话,PendingIntent更像是一个下订单的人,

因为它既要负责将订单发出去,也要负责订单发送后的处理,

比如发送成功后要准备验收订单货物,发送 失败后要重发还是取消订单等操作。


开发者可以通过调用三种不同方式来得到一个PendingIntent实例。

getActivity(Context, int, Intent, int)

getBroadcast(Context, int, Intent, int)

getService(Context, int, Intent, int)


getBroadcast

通过该函数获得的PendingIntent将会 扮演一个广播的功能,就像调用 Context.sendBroadcast()函数一样。

当系统通过它要发送一个intent时要采用广播的形式,并且在该intent中会包含相应的 intent接收对象,

当然这个对象我们可以在创建PendingIntent的时候指定,也可以通过ACTION 和CATEGORY等描述让系统自动找到该行为处理对象。

  1. Intent intent =  new  Intent(AlarmController. this , OneShotAlarm. class );  
  2. PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this ,  0 , intent,  0);  
Java代码 
  1. Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);  
  2. PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this0, intent, 0);  


getActivity

通过该函数获得的PendingIntent可以直 接启动新的activity, 就像调用 Context.startActivity(Intent)一样.

不过值得注意的是要想这个新的Activity不再是当前进程存在的Activity 时。我们在intent中必须使用Intent.FLAG_ACTIVITY_NEW_TASK.

  1. // The PendingIntent to launch our activity if the user selects this notification   
  2. PendingIntent contentIntent = PendingIntent.getActivity(this ,  0 ,   new  Intent( this, AlarmService. class ),  0 );  
Java代码 
  1. // The PendingIntent to launch our activity if the user selects this notification  
  2. PendingIntent contentIntent = PendingIntent.getActivity(this0,  new Intent(this, AlarmService.class), 0);  


getService

通过该函数获得的PengdingIntent可以直接启动新的Service,就像调用Context.startService()一样。

  1. // Create an IntentSender that will launch our service, to be scheduled   
  2.     // with the alarm manager.   
  3.     mAlarmSender = PendingIntent.getService(AlarmService.this ,  
  4.                 0 ,  new  Intent(AlarmService. this , AlarmService_Service. class ),  0);  

写一个android小闹钟

2、编写界面:直接修改layout中的main.xml文件,代码如下:

 

 

Xml代码  深入学习android之AlarmManager
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:gravity="center_vertical"  
  7.     >  
  8. <Button    
  9.     android:id="@+id/timeBtn"  
  10.     android:layout_width="fill_parent"   
  11.     android:layout_height="wrap_content"   
  12.     android:text="@string/time"  
  13.     android:textSize="20sp"  
  14.     />  
  15. <Button    
  16.     android:id="@+id/cancelAlarmBtn"  
  17.     android:layout_width="fill_parent"   
  18.     android:layout_height="wrap_content"   
  19.     android:text="@string/cancelAlarm"  
  20.     />      
  21. </LinearLayout>  



Java代码  深入学习android之AlarmManager
  1.      timeBtn.setOnClickListener(new Button.OnClickListener(){  
  2. @Override  
  3. public void onClick(View arg0) {  
  4.     Log.d(TAG, "click the time button to set time");  
  5.     calendar.setTimeInMillis(System.currentTimeMillis());  
  6.     new TimePickerDialog(Alarm.this,new TimePickerDialog.OnTimeSetListener() {  
  7.         @Override  
  8.         public void onTimeSet(TimePicker arg0, int h, int m) {  
  9.             //更新按钮上的时间  
  10.             timeBtn.setText(formatTime(h,m));  
  11.             //设置日历的时间,主要是让日历的年月日和当前同步  
  12.             calendar.setTimeInMillis(System.currentTimeMillis());  
  13.             //设置日历的小时和分钟  
  14.             calendar.set(Calendar.HOUR_OF_DAY, h);  
  15.             calendar.set(Calendar.MINUTE, m);  
  16.             //将秒和毫秒设置为0  
  17.             calendar.set(Calendar.SECOND, 0);  
  18.             calendar.set(Calendar.MILLISECOND, 0);  
  19.             //建立Intent和PendingIntent来调用闹钟管理器  
  20.             Intent intent = new Intent(Alarm.this,AlarmReceiver.class);  
  21.             PendingIntent pendingIntent = PendingIntent.getBroadcast(Alarm.this0, intent, 0);  
  22.             //获取闹钟管理器  
  23.             AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);  
  24.             //设置闹钟  
  25.             alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);  
  26.             alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10*1000, pendingIntent);  
  27.             Toast.makeText(Alarm.this"设置闹钟的时间为:"+String.valueOf(h)+":"+String.valueOf(m), Toast.LENGTH_SHORT).show();  
  28.             Log.d(TAG, "set the time to "+formatTime(h,m));  
  29.         }  
  30.     },calendar.get(Calendar.HOUR_OF_DAY),calendar.get(Calendar.MINUTE),true).show();                  
  31. }  
  32.      });  

  代码里面有注释,这里就不多解释了,其中new TimePickerDialog为创建时间选择对话框。为了能够看到效果,我给闹钟添加了重复提醒:alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10*1000, pendingIntent);

还要为取消闹钟按钮添加事件监听器:

 

Java代码  深入学习android之AlarmManager
  1. //取消闹钟按钮事件监听  
  2.         final Button cancelAlarmBtn = (Button)findViewById(R.id.cancelAlarmBtn);  
  3.         cancelAlarmBtn.setOnClickListener(new Button.OnClickListener(){  
  4.             @Override  
  5.             public void onClick(View arg0) {  
  6.                 Intent intent = new Intent(Alarm.this,AlarmReceiver.class);  
  7.                 PendingIntent pendingIntent = PendingIntent.getBroadcast(Alarm.this0, intent, 0);  
  8.                 //获取闹钟管理器  
  9.                 AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);  
  10.                 alarmManager.cancel(pendingIntent);  
  11.                 Toast.makeText(Alarm.this"闹钟已经取消!", Toast.LENGTH_SHORT).show();  
  12.             }  
  13.         });  

  在点击取消闹钟按钮时,取消之前设置的闹钟,核心代码就4行。

 

 

4、编写广播接收器,用来接收闹钟的广播事件,然后进行相关处理,

 

Java代码  深入学习android之AlarmManager
  1. public class AlarmReceiver extends BroadcastReceiver {  
  2.   
  3.     /* (non-Javadoc) 
  4.      * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent) 
  5.      */  
  6.     @Override  
  7.     public void onReceive(Context arg0, Intent data) {  
  8.         Log.d(Alarm.TAG, "the time is up,start the alarm...");  
  9.         Toast.makeText(arg0, "闹钟时间到了!", Toast.LENGTH_SHORT).show();  
  10.     }  
  11. }  

 

这个代码就很简单了,主要是要继承 BroadcastReceiver 这个类,然后重写onRecive方法。onRecive方法在闹钟的时间达到之后会执行,在这里我们可以做自己的事情,比如启动某个程序,或者播放铃声,我这里就是简单的提示一下,使用的是Toast。

 

5、在android的AndroidManifest.xml文件中注册广播接收器:

Xml代码  深入学习android之AlarmManager
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"      
  2. package="com.ql.activity"  
  3.       android:versionCode="1"  
  4.       android:versionName="1.0">  
  5.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  6.          <receiver android:name=".AlarmReceiver" android:process=":remote" />  
  7.         <activity android:name=".Alarm"  
  8.                   android:label="@string/app_name">  
  9.             <intent-filter>  
  10.                 <action android:name="android.intent.action.MAIN" />  
  11.                 <category android:name="android.intent.category.LAUNCHER" />  
  12.             </intent-filter>  
  13.         </activity>  
  14.   
  15.     </application>  
  16.     <uses-sdk android:minSdkVersion="8" />  
  17. </manifest>   

  核心的配置为<receiver android:name=".AlarmReceiver" android:process=":remote" />

这也是闹钟程序的关键,如果不做这个配置,那么时间到了之后,闹钟将不会提示。

 

到此为止,我们的小闹钟程序就结束了,接下来就是到模拟器上测试,运行截图如上图。程序源代码见附件。