1. 程式人生 > >AlarmManager定時不準確

AlarmManager定時不準確

    今天用AlarmManager做定時功能期間,粗心大意之下, 踩了個坑,在此記錄一下,提醒自己的同時希望能幫到其他小夥伴。首先申明一下,本文所要講的時間不準確問題不是系統省電模式引起的問題,至於本人解決省電導致的定時時間不準確的方案,在此就不加以複述,為啥?因為我是做系統開發,不用考慮省電,並且我懶,直接改底層,大部分小夥伴們採用不了!

    主要表現就是:明明自己定好了一定時間後的pendingIntent,但到了自認為的時間後,並沒有被觸發。

    AlarmManger主要提供了5個設定定時功能的方法:

set(int type, long triggerAtMillis, PendingIntent operation); setRepeating(int type, long triggerAtMillis,long intervalMillis, PendingIntent operation); setInexactRepeating(int type, long triggerAtMillis,long intervalMillis, PendingIntent operation); setExact(int type, long triggerAtMillis, PendingIntent operation); setWindow(int type, long triggerAtMillis, long windowLengthMillis,PendingIntent operation);

    注意啦,這五個API的前兩個引數都是type和triggerAtMillis,而關鍵的坑就在這裡,type一共有四種類型,如下:

AlarmManager.ELAPSED_REALTIME; //相對時間!裝置睡眠狀態下不可用。 AlarmManager.ELAPSED_REALTIME_WAKEUP; //相對時間!裝置睡眠狀態下可用。 AlarmManager.RTC_WAKEUP; //絕對時間!裝置睡眠狀態下不可用。 AlarmManager.RTC; //絕對時間!裝置睡眠狀態下不可用。

    看到註解沒,相對時間和絕對時間!對,問題就在這裡!千萬注意,如果是相對時間,那麼計算triggerAtMillis就需要使用SystemClock.elapsedRealtime();如果是絕對時間,那麼計算  triggerAtMillis時使用System.currentTimeMillis()或者calendar.getTimeInMillis()。

    如果沒講明白的話,舉個例子,當前時間是08:00,需要設定一個5小時後執行的操作:在type為相對時間,triggerAtMillis=SystemClock.elapsedRealtime()+5*60*60*1000;在type為絕對時間, triggerAtMillis=System.currentTimeMillis()+5*60*60*1000。

    最後解釋一下相對時間和絕對時間:

    相對時間——裝置boot後到當前經歷的時間,SystemClock.elapsedRealtime()獲取到的是相對時間。

    絕對時間——1970年1月1日到當前經歷的時間,System.currentTimeMillis()和C

alendar.getTimeInMillis()獲取到的都是絕對時間。