簡體   English   中英

喚醒鎖和打瞌睡模式

[英]Wakelock and doze mode

根據 Android Marshmallow 文檔,當系統處於打瞌睡模式時,任何喚醒鎖都會被忽略。 但是我不清楚喚醒鎖是否會阻止打瞌睡模式。

根據一些測試,在安裝了Android 6.0最終版本(?)的情況下使用Nexus 5:

  • 持有PARTIAL_WAKE_LOCK不足以阻止打ze模式-即使您擁有WakeLock並嘗試進行常規工作(例如, setExactAndAllowWhileIdle()以每分鍾獲得控制權setExactAndAllowWhileIdle() ,設備setExactAndAllowWhileIdle()

  • 保持上使用屏幕android:keepScreenOn (或Java等效)中,用在屏幕上, 足以阻斷打盹模式

  • 在關閉屏幕(用戶按下電源按鈕)的情況下,使用android:keepScreenOn (或Java等效語言)保持屏幕打開不足以阻止打ze模式

IOW,視頻播放器等在用戶觀看視頻時不會受到影響,即使播放器可能不移動也不在充電。 但是,如果用戶按下“電源”按鈕,您將重新陷入打Do的危險。

我還沒有嘗試使用FULL_WAKE_LOCK (我希望行為與android:keepScreenOn相同,但我不確定)。

有趣

Google在Android 6.0中擁有的時鍾應用程序可以完全阻止打ze模式:

  1. 在時鍾應用中,設置從現在起小於60分鍾的鬧鍾
  2. 關閉設備
  3. 在控制台中設置$ adb shell dumpsys電池拔出
  4. 在控制台中設置$ adb shell dumpsys deviceidle步驟

狀態保持為“已步進至:活動”

如果您設置的鬧鍾時間從現在開始> 60分鍾,則它將正常工作(設備可能會進入空閑狀態)。 但是,一旦警報小於60分鍾,則設備會從休眠狀態安靜地喚醒,因為狀態再次返回“活動”(而不是“ IDLE_MAINTENANCE”)。

我真的很想知道他們是如何做到的!

-編輯-

似乎是setAlarmClock()在默認情況下具有此行為。 這對於某些用例可能會有所幫助。

對於以上評論討論,這不是對該問題的答案。 通常,這是為了闡明應用程序在打Do模式下的行為。 在我的測試應用中,我嘗試每2分鍾獲取一次GPS位置,GPS信號強度一直都足夠。

測試條件:

  • Nexus 9,Android M預覽版,內部版本MPA44I
  • “忽略優化”
  • setExactAndAllowWhileIdle(),間隔2分鍾
  • 每個操作都有1分鍾的超時時間來獲取GPS定位信息,並被部分喚醒鎖包圍
  • 日志已寫入SQLiteOpenHelper.getWritableDatabase()

打Do模式的GPS測試日志:

1   2015-09-04 - 12:14  GPS ok (device left stationary unplugged)
2   2015-09-04 - 12:16  GPS ok
3   2015-09-04 - 12:18  GPS ok
4   2015-09-04 - 12:20  GPS ok
5   2015-09-04 - 12:22  GPS ok
6   2015-09-04 - 12:24  GPS ok
7   2015-09-04 - 12:26  GPS ok
8   2015-09-04 - 12:28  GPS ok
9   2015-09-04 - 12:30  GPS ok
10  2015-09-04 - 12:32  GPS ok
11  2015-09-04 - 12:34  GPS ok
...
31  2015-09-04 - 13:14  GPS ok
32  2015-09-04 - 13:16  GPS ok
33  2015-09-04 - 13:18  GPS ok
34  2015-09-04 - 13:20  GPS ok
35  2015-09-04 - 13:22  GPS ok
36  2015-09-04 - 13:24  GPS ok
37  2015-09-04 - 13:26  GPS ok (entering Doze mode some time after)
38  2015-09-04 - 13:42  GPS failed, active millis: 60174 (idle)
39  2015-09-04 - 13:57  GPS failed, active millis: 60128 (idle)
40  2015-09-04 - 14:12  GPS failed, active millis: 60122 (idle)
41  2015-09-04 - 14:16  GPS ok (idle maintenance)
42  2015-09-04 - 14:18  GPS ok (idle maintenance)
43  2015-09-04 - 14:20  GPS ok (idle maintenance)
44  2015-09-04 - 14:22  GPS ok (idle maintenance)
45  2015-09-04 - 14:38  GPS failed, active millis: 60143 (idle)
46  2015-09-04 - 14:53  GPS failed, active millis: 60122 (idle)
47  2015-09-04 - 15:08  GPS failed, active millis: 60068 (idle)
48  2015-09-04 - 15:23  GPS failed, active millis: 60138 (idle)
49  2015-09-04 - 15:38  GPS failed, active millis: 60140 (idle)
50  2015-09-04 - 15:53  GPS failed, active millis: 60131 (idle)
51  2015-09-04 - 16:08  GPS failed, active millis: 60185 (idle)
52  2015-09-04 - 16:12  GPS ok (ending Doze mode - power button on)

現在,我再次查看日志,我注意到一個非常奇怪的行為:“忽略優化”為OFF的同一測試顯示出基本相同的結果(如應有的結果),但大多數情況下超時未按預期進行,我得到了閑置時,“活動毫秒”的范圍為〜330000(約為超時時間的5倍)或什至約為580000(約為超時時間的10倍)。 我無法解釋這種奇怪的行為,但似乎表明在“打mode”模式下設置“忽略優化”實際上確實有一些效果。

編輯:上面描述的“奇怪”行為現已記錄 :僅在“忽略優化”為ON時,您才能在打ze空閑模式下保持部分喚醒鎖。

據我所探索,當更深的starts睡開始時,所有喚醒鎖(除了具有當前前台服務的應用所持有的喚醒鎖之外)都將被丟棄。 打ze的全部目的是讓“相關條件”發生時讓系統進入休眠狀態。因此,不錯,鎖並不是我想太多的事情。

我看到的方式JobScheduler是將來進行調度,后台任務等的方式。 盡管從開發人員手中奪走了一些控制權,但是我猜這是框架人員為了電池壽命而采取的行動。 這更像是“觸發並希望事情或多或少按時發生”。

談到您的用例, JobScheduler有一個onStopJob回調函數,以知道您的作業的執行何時停止(出於任何原因-例如wifi被切換),您需要采取適當的措施,例如將作業重新安排到下一個維護窗口。 從文檔:

一個直接的后果是系統將不再為您保留喚醒鎖。

我在 Android 13(在Google Pixel 7 Pro上)中發現setExactAndAllowWhileIdle()實際上有效,前提是用戶手動禁用應用程序的電池優化。 這是在應用程序的電池使用設置中完成的,如此所述。

我不知道如何在 Android 10 on a Huawei P20 Pro上執行此操作,但我並沒有太努力。

所以我的建議是先用一些手機進行試驗,以更好地了解各種 Android 版本和 phone.networks 的工作原理。

然后更改您的應用程序以檢查設置並告訴用戶是否需要更改,並提供打開應用程序的設置。 (請記住,您通常不知道手機制造商或 .network 是如何定制手機的,因此如果說明過於詳細,可能會與實際情況不符。)

此外,在您的應用程序中,檢查您的 function 是否被呼叫遲到,如果是,請告訴用戶與您聯系以進行故障排除。

我不認為可以通過編程方式更改電池使用設置。 我什至無法打開相應的設置 UI(即使在添加了我認為必要的權限之后),但只能打開通用設置頁面,用戶可以從那里導航。 所以:

// Check doze setting
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName());
// Show the app's setting window
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM