1、AlarmManager,顧名思義,就是“提醒”,是Android中常用的一種系統級別的提示服務,可以實現從指定時間開始,以一個固定的間隔時間執行某項操作,所以常常與廣播(Broadcast)連用,實現鬧鍾等提示功能
2、AlarmManager的常用方法有三個:
(1)set(int type,long startTime,PendingIntent pi);
該方法用於設置一次性鬧鍾,第一個參數表示鬧鍾類型,第二個參數表示鬧鍾執行時間,第三個參數表示鬧鍾響應動作。
(2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
該方法用於設置重復鬧鍾,第一個參數表示鬧鍾類型,第二個參數表示鬧鍾首次執行時間,第三個參數表示鬧鍾兩次執行的間隔時間,第三個參數表示鬧鍾響應動作。
(3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
該方法也用於設置重復鬧鍾,與第二個方法相似,不過其兩個鬧鍾執行的間隔時間不是固定的而已。
3、三個方法各個參數詳悉:
(1)int type:鬧鍾的類型,常用的有5個值: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的使用機制有的稱呼為全局定時器,有的稱呼為鬧鍾。通過對它的使用,個人覺得叫全局定時器比較合適,其實它的作用和Timer有點相似。都有兩種相似的用法:(1)在指定時長后執行某項操作(2)周期性的執行某項操作
AlarmManager對象配合Intent使用,可以定時的開啟一個Activity,發送一個BroadCast,或者開啟一個Service.
下面的代碼詳細的介紹了兩種定時方式的使用:
(1)在指定時長后執行某項操作
//操作:發送一個廣播,廣播接收后Toast提示定時操作完成 Intent intent =new Intent(Main.this, alarmreceiver.class); intent.setAction("short"); PendingIntent sender= PendingIntent.getBroadcast(Main.this, 0, intent, 0); //設定一個五秒后的時間 Calendar calendar=Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.SECOND, 5); AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE); alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender); //或者以下面方式簡化 //alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+5*1000, sender);
//注意:receiver記得在manifest.xml注冊 public static class alarmreceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(intent.getAction().equals("short")){ Toast.makeText(context, "short alarm", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(context, "repeating alarm",Toast.LENGTH_LONG).show(); } } }
AlarmManager類型如下:
AlarmManager.RTC,硬件鬧鍾,不喚醒手機(也可能是其它設備)休眠;當手機休眠時不發射鬧鍾。
AlarmManager.RTC_WAKEUP,硬件鬧鍾,當鬧鍾發射時喚醒手機休眠;
AlarmManager.ELAPSED_REALTIME,真實時間流逝鬧鍾,不喚醒手機休眠;當手機休眠時不發射鬧鍾。
AlarmManager.ELAPSED_REALTIME_WAKEUP,真實時間流逝鬧鍾,當鬧鍾發射時喚醒手機休眠;
RTC鬧鍾和ELAPSED_REALTIME最大的差別就是前者可以通過修改手機時間觸發鬧鍾事件,后者要通過真實時間的流逝,即使在休眠狀態,時間也會被計算。
(2)周期性的執行某項操作
Intent intent =new Intent(Main.this, alarmreceiver.class); intent.setAction("repeating"); PendingIntent sender=PendingIntent .getBroadcast(Main.this, 0, intent, 0); //開始時間 long firstime=SystemClock.elapsedRealtime(); AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE); //5秒一個周期,不停的發送廣播 am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstime, 5*1000, sender);
AlarmManager的setRepeating()相當於Timer的Schedule(task,delay,peroid);有點差異的地方時Timer這個方法是指定延遲多長時間以后開始周期性的執行task;
AlarmManager的取消:(其中需要注意的是取消的Intent必須與啟動Intent保持絕對一致才能支持取消AlarmManager)
Intent intent =new Intent(Main.this, alarmreceiver.class); intent.setAction("repeating"); PendingIntent sender=PendingIntent .getBroadcast(Main.this, 0, intent, 0); AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE); alarm.cancel(sender);