1. 程式人生 > >AlarmManager計時不準,在手機滅屏後延遲的問題

AlarmManager計時不準,在手機滅屏後延遲的問題



應用需要週期性的提醒使用者,但是在使用alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime,delay,pendIntent) 設定週期性廣播後,始終無法完美體驗這一效果,搞得本書生是在是頭大呀!

查閱API發現對這一方法的解釋為在API19後將不再準時,需要參考setWindow()或者setExact()來設定精準定時的廣播,似乎是找到救命稻草啦~。~

然而,,,,萬事總是逃不掉然而,,,

在使用setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendIntent)方法,並在onReceiver()中再次呼叫setExact()以期能夠實現週期性傳送廣播的效果後,
卻發現問題還是沒有得到解決,這樣做只是保證了在應用前臺的情況下可以準時傳送廣播,在手機熄屏並且未連線電源線的情況下,廣播依然會被延遲;

這時意識到自己的測試機是android6.0,會不會有關係呢?順著這條線終於找到了導致後臺廣播不能準時提醒的罪魁禍首!原來google為了緩解Android手機飽受詬病的耗電問題,在6.0有引入了新的省電機制——Doze模式,好嘛,困擾我許久的問題終於解決了,,,,關於Doze模式請戳這裡Android M新特性Doze and App Standby模式詳解

在android6.0之後,如果想繼續保持Alarm在手機處於所謂Doze模式時仍然能夠被即時響應,則需要使用AlarmManager新提供的兩個方法setAndAllowWhileIdle()或者setExactAndAllowWhileIdle(),饒了一大圈,還是回到AlarmManager是不是讓人很淡疼。。。

最後修改程式碼為:

    AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(action);
    PendingIntent pendIntent = PendingIntent.getBroadcast(getApplicationContext(),requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    if (Build.VERSION.SDK
_INT>=Build.VERSION_CODES.M) { alarmMgr.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendIntent); }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ alarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendIntent); }else{ alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendIntent); }

以前都是看別人的部落格也受益匪淺,這是博主第一次發部落格,希望對與我碰到同一問題的同鞋能有所幫助,嘿嘿:)