副標題:流氓應用Android6.0生存指南

我跟你們說,周三給五兒子升級了android6.0,周四起床失敗,周五上課在下課前趕到,簡直整個人都和吃了蒼蠅一樣。

而一切的根源都是因為我用了第三方鬧鐘應用而Android又踏馬改休眠機制啦!

於是google搜了一下,我一看,哇!

Starting from Android 6.0 (API level 23), Android introduces two power-saving features that extend battery life for users by managing how apps behave when a device is not connected to a power source. Dozereduces battery consumption by deferring background CPU and network activity for apps when the device is unused for long periods of time. App Standby defers background network activity for apps with which the user has not recently interacted.

Doze is particularly likely to affect activities thatAlarmManager alarms and timers manage, because alarms in Android 5.1 (API level 22) or lower do not fire when the system is in Doze.

To help with scheduling alarms, Android 6.0 (API level 23) introduces two new AlarmManager methods:setAndAllowWhileIdle() and setExactAndAllowWhileIdle(). With these methods, you can set alarms that will fire even if the device is in Doze.

引用來源:Optimizing for Doze and App Standby | Android Developers

而我們都知道,鬧鐘都是用AlarmManager.setExact來實現核心功能的,而從AlarmManager | Android Developers可以知道,setExact和setExactAndAllowWhileIdle的參數列表是一致的,這樣就以為著我們可以反編譯直接修改API來實現適配Android6.0。

我用的第三方鬧鐘應用叫myClock 2,這個應用已經一萬年沒有更新惹。

通過grep . -re AlamManager|grep Exact查找AlarmManager調用(注意setExact是在4.4 Kitkat中引入的新API,如果鬧鐘應用更古老,可能使用的直接是set),然後將它改成setExactAndAllowWhileIdle。

注意還有一個暗坑:

Note: Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 15 minutes per app.

Google還提供了測試是否起效的方法

  1. 插入USB調試
  2. 關閉屏幕
  3. 重複第二步數次直到屏幕顯示Stepped to: IDLE
  4. 現在進入Doze模式

 

引申:

可以使用Xposed將應用的setExactAndAllowWhileIdle改成setExact,setAndAllowWhileIdle改成set,這樣開啟屏幕立馬能得到推送之類的消息,休眠之後就不會再被喚醒。不知道綠色守護會不會這麼搞。