對應AlarmManage有一個AlarmManagerServie服務程式,該服務程式才是正真提供鬧鈴服務的,它主要維護應用程式註冊下來的各類鬧鈴並適時的設定即將觸發的鬧鈴給鬧鈴裝置(在系統中,linux實現的裝置名稱為”/dev/alarm”),並且一直監聽鬧鈴裝置,一旦有鬧鈴觸發或者是鬧鈴事件發生,AlarmManagerServie服務程式就會遍曆鬧鈴列表找到相應的註冊鬧鈴並發出廣播。該服務程式在系統啟動時被系統服務程式system_service啟動並初始化鬧鈴裝置(/dev/alarm)。當然,在JAVA層的AlarmManagerService與Linux
Alarm驅動程式介面之間還有一層封裝,那就是JNI。
AlarmManager將應用與服務分割開來後,使得應用程式開發人員不用關心具體的服務,而是直接通過AlarmManager來使用這種服務。這也許就是客戶/服務模式的好處吧。AlarmManager與AlarmManagerServie之間是通過Binder來通訊的,他們之間是多對一的關係。
在android系統中,AlarmManage提供了3個介面5種類型的鬧鈴服務。
3個介面:
view plaincopy to clipboardprint?
- // 取消已經註冊的與參數匹配的鬧鈴
- void cancel(PendingIntent operation)
-
- //註冊一個新的鬧鈴
- void set(int type, long triggerAtTime, PendingIntent operation)
-
- //註冊一個重複類型的鬧鈴
- void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)
-
- //設定時區
- void setTimeZone(String timeZone)
Java代碼
- // 取消已經註冊的與參數匹配的鬧鈴
- void cancel(PendingIntent operation)
- //註冊一個新的鬧鈴
- void set(int type, long triggerAtTime, PendingIntent operation)
- //註冊一個重複類型的鬧鈴
- void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)
- //設定時區
- void setTimeZone(String timeZone)
// 取消已經註冊的與參數匹配的鬧鈴<br />void cancel(PendingIntent operation)<br /> //註冊一個新的鬧鈴<br />void set(int type, long triggerAtTime, PendingIntent operation)<br /> //註冊一個重複類型的鬧鈴<br />void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)<br /> //設定時區<br />void setTimeZone(String timeZone)<br />
5個鬧鈴類型
view plaincopy to clipboardprint?
- public static final int ELAPSED_REALTIME
- //當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是相對時間,是從系統啟動後開始計時的,包括睡眠時間,可以通過調用SystemClock.elapsedRealtime()獲得。系統值是3 (0x00000003)。
-
- public static final int ELAPSED_REALTIME_WAKEUP
- //能喚醒系統,用法同ELAPSED_REALTIME,系統值是2 (0x00000002) 。
-
- public static final int RTC
- //當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是絕對時間,所用時間是UTC時間,可以通過調用 System.currentTimeMillis()獲得。系統值是1 (0x00000001) 。
-
- public static final int RTC_WAKEUP
- //能喚醒系統,用法同RTC類型,系統值為 0 (0x00000000) 。
-
- Public static final int POWER_OFF_WAKEUP
- //能喚醒系統,它是一種關機鬧鈴,就是說裝置在關機狀態下也可以喚醒系統,所以我們把它稱之為關機鬧鈴。使用方法同RTC類型,系統值為4(0x00000004)。
Java代碼
- public
- static final int ELAPSED_REALTIME
-
- //當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是相對時間,是從系統啟動後開始計時的,包括睡眠
- 時間,可以通過調用SystemClock.elapsedRealtime()獲得。系統值是3 (0x00000003)。
- public static final int ELAPSED_REALTIME_WAKEUP
- //能喚醒系統,用法同ELAPSED_REALTIME,系統值是2 (0x00000002) 。
- public static final int RTC
-
- //當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是絕對時間,所用時間是UTC時間,可以通過調用
- System.currentTimeMillis()獲得。系統值是1 (0x00000001) 。
- public static final int RTC_WAKEUP
- //能喚醒系統,用法同RTC類型,系統值為 0 (0x00000000) 。
- Public static final int POWER_OFF_WAKEUP
-
- //能喚醒系統,它是一種關機鬧鈴,就是說裝置在關機狀態下也可以喚醒系統,所以我們把它稱之為關機鬧鈴。使用方法同RTC類型,系統值為
- 4(0x00000004)。
public<br /> static final int ELAPSED_REALTIME</p><p>//當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是相對時間,是從系統啟動後開始計時的,包括睡眠<br />時間,可以通過調用SystemClock.elapsedRealtime()獲得。系統值是3 (0x00000003)。<br /> public static final int ELAPSED_REALTIME_WAKEUP<br /> //能喚醒系統,用法同ELAPSED_REALTIME,系統值是2 (0x00000002) 。<br /> public static final int RTC</p><p>//當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是絕對時間,所用時間是UTC時間,可以通過調用<br /> System.currentTimeMillis()獲得。系統值是1 (0x00000001) 。<br /> public static final int RTC_WAKEUP<br /> //能喚醒系統,用法同RTC類型,系統值為 0 (0x00000000) 。<br /> Public static final int POWER_OFF_WAKEUP</p><p>//能喚醒系統,它是一種關機鬧鈴,就是說裝置在關機狀態下也可以喚醒系統,所以我們把它稱之為關機鬧鈴。使用方法同RTC類型,系統值為<br />4(0x00000004)。<br />
注意一個重要的參數PendingIntent。這個PendingIntent可以說是 Intent的進一步封裝,他既包含了Intent的描述又是Intent行為的執行(這種定義也許不太嚴格),如果將Intent比作成一個訂單的話,PendingIntent更像是一個下訂單的人,因為它既要負責將訂單發出去,也要負責訂單發送後的處理,比如發送成功後要準備驗收訂單貨物,發送失敗後要重發還是取消訂單等操作。開發人員可以通過調用getActivity(Context,
int, Intent, int)
getBroadcast(Context, int, Intent, int)
getService(Context, int, Intent, int)
三種不同方式來得到一個PendingIntent執行個體。
getBroadcast——通過該函數獲得的PendingIntent將會扮演一個廣播的功能,就像調用 Context.sendBroadcast()函數一樣。當系統通過它要發送一個intent時要採用廣播的形式,並且在該intent中會包含相應的 intent接收對象,當然這個對象我們可以在建立PendingIntent的時候指定,也可以通過ACTION 和CATEGORY等描述讓系統自動找到該行為處理對象。
view plaincopy to clipboardprint?
- Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
- PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this, 0, intent, 0);
Java代碼
- Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
- PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this, 0, intent, 0);
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);<br />PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this, 0, intent, 0);
getActivity——通過該函數獲得的PendingIntent可以直接啟動新的activity, 就像調用 Context.startActivity(Intent)一樣.不過值得注意的是要想這個新的Activity不再是當前進程存在的Activity 時。我們在intent中必須使用Intent.FLAG_ACTIVITY_NEW_TASK.
view plaincopy to clipboardprint?
- // The PendingIntent to launch our activity if the user selects this notification
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, AlarmService.class), 0);
Java代碼
- // The PendingIntent to launch our activity if the user selects this notification
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, AlarmService.class), 0);
// The PendingIntent to launch our activity if the user selects this notification<br />PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, AlarmService.class), 0);
getService——通過該函數獲得的PengdingIntent可以直接啟動新的Service,就像調用Context.startService()一樣。
view plaincopy to clipboardprint?
- // Create an IntentSender that will launch our service, to be scheduled
- // with the alarm manager.
- mAlarmSender = PendingIntent.getService(AlarmService.this,
- 0, new Intent(AlarmService.this, AlarmService_Service.class), 0);