之前在Android 4.0時,alarmManager 沒什麼問題。後來android爲了優化系統耗電狀況,引入了doze模式,參見此頁android
https://developer.android.com/training/monitoring-device-state/doze-standby數據庫
簡單地說,系統會長時間待機後,會自動進入doze模式,這種模式裏,alarmManager啥的都很差用了,系統會自動從doze模式轉出來一小段時間,把剛在在doze裏被忽略的事件(好比說alarmManager)執行。這樣一來,alarmManager根本沒法定時調用了。網絡
其實,對於每一個應用,這個模式是能夠配置的,通常在 Settings > Battery > Battery Optimization,也能夠用代碼打開設置頁面,讓用戶設置,下面是一段別人寫的代碼:測試
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:user.zhuku.com")); startActivity(intent);
可是在android wear手錶上,好比華爲 watch2,是沒有這個設置項的,也就是說,手錶放置在桌子上,不使用,一段時間後,全部應用必定會停用。通過測試發現,手錶進入doze模式後,的確如開發文檔說的那樣,定時喚醒系統,而且頻率愈來愈低。優化
試了好多方法,好比JobService,setAndAllowWhileIdle 在 華爲手錶上,都沒法越過這個限制。spa
好在手錶有一個設定,就是帶在手上後,系統就不會進入doze模式了,不知道是使用的什麼方法判斷的手錶是否帶在手上。線程
測試基於 華爲 watch 2 ,andoroid 8.0 ,android wear 2.x,code
手錶長時間不帶的話,會進入doze模式,後臺任務都會中止,好在咱們的應用是要求用戶一直呆在手上,因此不用介意手錶doze後的狀況。
手錶進入doze後,再次移動手錶,系統會當即喚醒,後臺任務能夠繼續正常執行,知足咱們的需求 :用戶白天帶上手錶,系統執行跟蹤;晚上摘下,系統doze後中止跟蹤;次日再次帶上時,系統繼續跟蹤。blog
因爲手錶帶在手上時,手錶存在必定的移動,因此係統不會doze,理論上可使用任何後臺技術實現需求。咱們的demo中,使用的是系統alarm+後臺service 的方案。 系統中有3個alarm,第一個負責添加 sersor listener, 第二個負責移除 sensor listener,第三個負責觸發網絡請求,發送數據。這3個alarm按期向service中的線程發送message,觸發相應操做。事件
爲了減小耗電,目前是每分鐘開啓監控30秒,關閉監控30秒。爲了減小數據庫的數據量,目前是每3秒錄入一次數據。
demo是一款 在手錶上獨立運行的應用。充滿電後,可知足一個白天12小時的使用(wifi條件下)(大約20小時以上?)(晚上會進入doze,耗電不多)。
另外華爲手錶目前沒有發現 doze的白名單設置。
demo僅僅驗證了方案的可行性,具體實現時須要優化。好比把service bind上,去掉handler的使用。再好比針對新的alarm機制調整alarm的註冊和使用。再好比 對 front service 的notification界面 進行動態調整,讓用戶在通知欄看到更多的跟蹤信息。