深入學習android之AlarmManager


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代碼  收藏代碼
  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代碼  收藏代碼
  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代碼  收藏代碼
  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代碼  收藏代碼
  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代碼  收藏代碼
  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" />

這也是鬧鍾程序的關鍵,如果不做這個配置,那么時間到了之后,鬧鍾將不會提示。

 

到此為止,我們的小鬧鍾程序就結束了,接下來就是到模擬器上測試,運行截圖如上圖。程序源代碼見附件。

 




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com