Android之Alarm

1 簡介

Alarm是在預定的時間上觸發Intent的一種獨立的方法。

Alarm超出了應用程序的作用域,所以它們可以用於觸發應用程序事件或動作。在應用程序關閉之後,與Broadcast Receiver結合,它們可以變得尤其的強大,可以通過設置Alarm來啓動應用程序或者執行動作,而應用程序不需要打開或者處於活躍狀態。
舉個例子,你可以使用Alarm來實現一個鬧鐘程序,執行正常的網絡查詢,或者在“非高峯”時間安排耗時或有代價的操作。
對於僅在應用程序生命週期內發生的定時操作,Handler類與Timer和Thread類的結合是一個更好的選擇,它允許Android更好地控制系統資源。
Android中的Alarm在設備處於睡眠模式時仍保持活躍,它可以設置來喚醒設備;然而,所有的Alarm在設備重啓時都會被取消。

2 實現方法

Alarm的操作通過AlarmManager來處理,通過getSystemService可以獲得其系統服務,如下所示:
AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

2.1 添加Alarm

2.1.1 需要定義一個日曆對象mCal

private Calendar mCal = Calendar.getInstance();

2.1.2 獲取AlarmManager

AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

2.1.3 設置警告時間

//Sets the time of this Calendar.
mCal.setTimeInMillis(System.currentTimeMillis());
//Sets a field to the specified value.
mCal.set(Calendar.HOUR_OF_DAY, tPicker.getCurrentHour());
mCal.set(Calendar.MINUTE, tPicker.getCurrentMinute());
mCal.set(Calendar.SECOND, 0);
mCal.set(Calendar.MILLISECOND, 0);

2.1.4 註冊intent

需要注意的有兩點:第一,爲什麼要使用PendingIntent ;第二,PendingIntent獲取。

//由於Alarm是在預定的時間上觸發Intent的一種獨立的方法,所以需要使用PendingIntent,而且需要設定負責處理該PendingIntent的廣播類AlarmCaller.class。
Intent intent = new Intent(SettingsActivity.this, AlarmCaller.class);
PendingIntent sender = PendingIntent.getBroadcast(SettingsActivity.this, id, intent, 0);

1) PendingIntent和Intent的區別

Intent 表示一個目的,第一個參數表示所在類,第二個參數表示目標類。Intent 字面意思是意圖,即我們的目的,我們想要做的事情,在activity中,我們可以立即執行它。
PendingIntent 即是一個Intent的描述。PendingIntent 相當於對intent執行了包裝,我們不一定一定要馬上執行它,我們將其包裝後,傳遞給其他activity或application。這時,獲取到PendingIntent 的application 能夠根據裏面的intent 來得知發出者的意圖,選擇攔擊或者繼續傳遞或者執行。

2) PendingIntent的獲取

public static PendingIntent getBroadcast (Context context, int requestCode, Intent intent, int flags)
Retrieve a PendingIntent that will perform a broadcast, like calling Context.sendBroadcast().

Parameters
context The Context in which this PendingIntent should perform the broadcast.
requestCode Private request code for the sender (currently not used).
intent The Intent to be broadcast.
flags May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.

Returns
Returns an existing or new PendingIntent matching the given parameters. May return null only if FLAG_NO_CREATE has been supplied.

2.1.5 註冊Alarm

註冊Alarm有3種方法。

1) public void set (int type, long triggerAtTime, PendingIntent operation)
設置Alarm,但是隻提醒一次。

If there is already an alarm scheduled for the same IntentSender, it will first be canceled.
If the time occurs in the past, the alarm will be triggered immediately.

If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by filterEquals(Intent)), then it will be removed and replaced by this one.

2) public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)

設置Alarm,可以重複提醒多次,時間間隔由interval確定,但是這種重複提醒是不精確的。
Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour. These alarms are more power-efficient than the strict recurrences supplied by setRepeating(int, long, long, PendingIntent).

3) public void setRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)

設置Alarm,可以精確重複提醒多次,時間間隔由interval確定。
Schedule a repeating alarm. Note: for timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.

If there is already an alarm scheduled for the same IntentSender, it will first be canceled.

Like set(int, long, PendingIntent), except you can also supply a rate at which the alarm will repeat. This alarm continues repeating until explicitly removed with cancel(PendingIntent).

If the time occurs in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.


需要說明的是setRepeating的第一個參數type,主要有4種Alarm類型:


* RTC_WAKEUP
在指定的時刻(使用UTC格式)喚醒設備來觸發Intent。

Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off. Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.

* RTC
在一個顯式的時間(使用UTC格式)觸發Intent,但不喚醒設備。

Alarm time in System.currentTimeMillis() (wall clock time in UTC). This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.


* ELAPSED_REALTIME
從設備啓動後,如果流逝的時間達到總時間,那麼觸發Intent,但不喚醒設備。流逝的時間包括設備睡眠的任何時間。注意一點的是,時間流逝的計算點是自從它最後一次啓動算起。

Alarm time in SystemClock.elapsedRealtime() (time since boot, including sleep). This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.

* ELAPSED_REALTIME_WAKEUP
從設備啓動後,達到流逝的總時間後,如果需要將喚醒設備並觸發Intent。

Alarm time in SystemClock.elapsedRealtime() (time since boot, including sleep), which will wake up the device when it goes off.

//定義重啓Alarm的時間間隔
int mTimeInterval = 60 * 60 * 24 * 1000;
alarms.setRepeating(AlarmManager.RTC_WAKEUP, mCal.getTimeInMillis(), mTimeInterval,sender);


2.2 刪除Alarm

2.2.1 獲取AlarmManager

AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

2.2.2 註冊intent

Intent intent = new Intent(SettingsActivity.this, AlarmCaller.class);
PendingIntent sender = PendingIntent.getBroadcast(SettingsActivity.this, id, intent, 0);

2.2.3 取消Alarm註冊

alarms.cancel(sender);

public void cancel (PendingIntent operation)
Remove any alarms with a matching Intent. Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.

Parameters
operation IntentSender which matches a previously added IntentSender. 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章