AlarmManager使用
AlarmManager是Android中常用的一種系統級別的提示服務,在特定的時刻為我們廣播一個指定的Intent,為你的應用設定一個在未來某個時間喚醒的功能。
當鬧鐘響起,實際上是系統發出了為這個鬧鐘注冊的廣播,會自動開啟目標應用。
注冊的鬧鐘在設備睡眠的時候仍然會保留,可以選擇性地設置是否喚醒設備,但是當設備關機和重啟后,鬧鐘將會被清除。
對于常規的短時間計時操作(ticks, timeouts, etc),使用Handler處理更加方便和有效率。
在alarm的receiver的onReceive()方法被執行的時候,AlarmManager持有一個CPU喚醒鎖,這樣就保證了設備在處理完廣播之前不會sleep。一旦onReceive()方法返回,AlarmManager就會釋放這個鎖,表明一些情況下可能onReceive()方法一執行完設備就會sleep。如果你的alarmreceiver中調用了Context.startService(),那么很可能service還沒起來設備就sleep了。為了阻止這種情況,你的BroadcastReceiver和Service需要實現不同的喚醒鎖機制,來確保設備持續運行到service可用為止。
如果onReceive()方法里確實需要異步操作的話,可以用goAsync方法,然后在新開一個線程去執行。
如果onReceive()有過于耗時的操作,建議使用PendingIntent.getService()啟動Service方式來完成。
BroadcastReceiver onReceive()使用goAsync 執行異步操作例子:
@Overridepublic void onReceive(final Context context, final Intent intent) {final PendingResult result = goAsync();final PowerManager.WakeLock wl = AlarmAlertWakeLock.createPartialWakeLock(context);try {wl.acquire();} catch (Exception e) {e.printStackTrace();}AsyncHandler.post(new Runnable() {@Overridepublic void run() {LogUtils.writeAlarmLog("AlarmStateManager received intent " + intent);try {handleIntent(context, intent);result.finish();wl.release();} catch (Exception e) {e.printStackTrace();}}});}Alarm接口
1.cancel(PendingIntent operation)
?Remove any alarms with a matching Intent.
2.changeAlarmType(String pkgName, boolean wakeup)
3.getNextAlarmClock()
Gets information about the next alarm clock currently scheduled.
4.set(int type, long triggerAtMillis, PendingIntent operation)
Schedule an alarm.
5.setAlarmClock(AlarmManager.AlarmClockInfo info, PendingIntent operation)
Schedule an alarm that represents an alarm clock.
6.setExact(int type, long triggerAtMillis, PendingIntent operation)
Schedule an alarm to be delivered precisely at the stated time.
7.setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
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.
8.setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
Schedule a repeating alarm.
9.setTime(long millis)
Set the system wall clock time.
10.setTimeZone(String timeZone)
Set the system default time zone.
11.setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation)
Schedule an alarm to be delivered within a given window of time.
常用接口
1.public void?set/setExact(int type, long triggerAtMillis, PendingIntent operation)
?該方法用于設置一次性鬧鐘。
第一個參數int type 指定定時服務的類型,該參數接受如下值:
ELAPSED_REALTIME:?在指定的延時過后,發送廣播,但不喚醒設備(鬧鐘在睡眠狀態下不可用)。如果在系統休眠時鬧鐘觸發,它將不會被傳遞,直到下一次設備喚醒。
ELAPSED_REALTIME_WAKEUP:?在指定的延時過后,發送廣播,并喚醒設備(即使關機也會執行operation所對應的組件)。延時是要把系統啟動的時間SystemClock.elapsedRealtime()算進去的,具體用法看代碼。
RTC:?指定當系統調用System.currentTimeMillis()方法返回的值與triggerAtTime相等時啟動operation所對應的設備(在指定的時刻,發送廣播,但不喚醒設備)。如果在系統休眠時鬧鐘觸發,它將不會被傳遞,直到下一次設備喚醒(鬧鐘在睡眠狀態下不可用)。
RTC_WAKEUP:?指定當系統調用System.currentTimeMillis()方法返回的值與triggerAtTime相等時啟動operation所對應的設備(在指定的時刻,發送廣播,并喚醒設備)。即使系統關機也會執行 operation所對應的組件。
第二個參數triggerAtMillis表示觸發鬧鐘的時間。
第三個參數PendingIntent pi表示鬧鐘響應動作:
PendingIntent pi:是鬧鐘的執行動作,比如發送一個廣播、給出提示等等。PendingIntent是Intent的封裝類。需要注意的是:
啟動服務:如果是通過啟動服務來實現鬧鐘提示的話,PendingIntent對象的獲取就應該采用Pending.getService(Context c,int i,Intent intent,int j)方法;
啟動廣播:如果是通過廣播來實現鬧鐘提示的話,PendingIntent對象的獲取就應該采用PendingIntent.getBroadcast(Context c,inti,Intent intent,int j)方法;
啟動activity:如果是采用Activity的方式來實現鬧鐘提示的話,PendingIntent對象的獲取就應該采用PendingIntent.getActivity(Context c,inti,Intent intent,int j)方法。
如果這三種方法錯用了的話,雖然不會報錯,但是看不到鬧鐘提示效果。
注意:AndroidL開始,設置的alarm的觸發時間必須大于當前時間 5秒
AlarmManagerService中是通過PendingItent來標示一個Alarm的
2.public void?cancel?(PendingIntent operation)
移除intent相匹配的alarm(只要action,data, type,package,component,categories相等,就會被取消)。另外,應用被forcestoppackage殺掉之后,所有的alarm都會被移除。
3.public void?setRepeating(int type,long startTime,long intervalTime,PendingIntent pi)
設置一個周期性執行的定時服務。第一個參數表示鬧鐘類型,第二個參數表示鬧鐘首次執行時間,第三個參數表示鬧鐘兩次執行的間隔時間,第三個參數表示鬧鐘響應動作。
注意:該方法提供了設置周期鬧鐘的入口,鬧鐘執行時間嚴格按照startTime來處理,使用該方法需要的資源更多,不建議使用。
4.public void?setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi)
該方法也用于設置重復鬧鐘,與第二個方法相似,不過其兩個鬧鐘執行的間隔時間不是固定的而已。它相對而言更省電(power-efficient)一些,因為系統可能會將幾個差不多的鬧鐘合并為一個來執行,減少設備的喚醒次數。第三個參數intervalTime為鬧鐘間隔,內置的幾個變量如下:
INTERVAL_DAY:?設置鬧鐘,間隔一天
INTERVAL_HALF_DAY:?設置鬧鐘,間隔半天
INTERVAL_FIFTEEN_MINUTES:設置鬧鐘,間隔15分鐘
INTERVAL_HALF_HOUR:?設置鬧鐘,間隔半個小時
INTERVAL_HOUR:?設置鬧鐘,間隔一個小時
AndroidL開始repeat的周期必須大于60秒
設置一個鬧鐘和取消一個鬧鐘的例子:
private static class AlarmManagerStateChangeScheduler implements StateChangeScheduler {@Overridepublic void scheduleInstanceStateChange(Context context, Calendar time,AlarmInstance instance, int newState) {long timeInMillis = time.getTimeInMillis();Intent stateChangeIntent = createStateChangeIntent(context, ALARM_MANAGER_TAG, instance,newState, VALUE_CHANGE_STATE_BY_SCHEDULE);// Treat alarm state change as high priority, use foreground broadcastsstateChangeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);PendingIntent pendingIntent = PendingIntent.getService(context, instance.hashCode(),stateChangeIntent, PendingIntent.FLAG_UPDATE_CURRENT);//設置一個鬧鐘AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);if (CommonUtils.isMOrLater()) {am.setExactAndAllowWhileIdle(ReflectUtils.getRTC_BOOT_WAKEUP()/*AlarmManager.RTC_WAKEUP*/, timeInMillis, pendingIntent);LogUtils.writeAlarmLog("Scheduling state change success by setExactAndAllowWhileIdle");} else if (CommonUtils.isKitKatOrLater()) {am.setExact(ReflectUtils.getRTC_BOOT_WAKEUP()/*AlarmManager.RTC_WAKEUP*/, timeInMillis, pendingIntent);LogUtils.writeAlarmLog("Scheduling state change success by setExact");} else {am.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);LogUtils.writeAlarmLog("Scheduling state change success not KitKatOrLater");}}@Overridepublic void cancelScheduledInstanceStateChange(Context context, AlarmInstance instance) {LogUtils.writeAlarmLog("cancelScheduledInstance instance id = " + instance.mId);// Create a PendingIntent that will match any one set for this instancePendingIntent pendingIntent = PendingIntent.getService(context, instance.hashCode(),createStateChangeIntent(context, ALARM_MANAGER_TAG, instance, null, null),PendingIntent.FLAG_NO_CREATE);//取消一個鬧鐘if (pendingIntent != null) {AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);am.cancel(pendingIntent);pendingIntent.cancel();ReflectUtils.cancelOnePoweroffAlarm(am, pendingIntent);}}}總結
以上是生活随笔為你收集整理的AlarmManager使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021数学建模C题思路数据挖掘
- 下一篇: padding 后尺寸变化 设置_pad