Android之Alarm

jopen 10年前發布 | 35K 次閱讀 Android Android開發 移動開發

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.thisid, 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.

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!