问题
TL;DR
Did the 'June 5, 2017' security updates for Android 7.1.2 cause Android to start ignoring the battery optimization whitelist (i.e. the thing that's meant to let an app disable Doze mode)?
And if so, how can an app now programmatically disable Doze mode if it has a use-case that requires the CPU and wifi be kept continuously active?
Context
I have an Android app which supports casting local audio files to a networked Chromecast receiver (using an embedded HTTP server to stream the file content to the receiver).
To get this working on Android M (in terms of not having the Chromecast session drop while the device is casting audio but otherwise idle), I had to use the approach in this answer to disable Doze mode.
Specifically, in my AndroidManifest.xml
I have:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
...and the following code executes whenever a Chromecast session is established:
if (Build.VERSION.SDK_INT >= 23) {
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (! pm.isIgnoringBatteryOptimizations(packageName)) {
//reguest that Doze mode be disabled
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
}
}
...and I'm also acquiring wake/wifi locks in the standard way, while Chromecast playback is active:
PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myapp-cast-server-cpu");
wakeLock.acquire();
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "myapp-cast-server-net");
wifiLock.acquire();
The app appears in the battery whitelist, and as recently as a few weeks ago this was all working fine. However, the app is now getting caught by Doze mode.
The testing device hasn't changed; it's a Google Pixel running Android 7.1.2. The only software change is that I installed the June 5, 2017 security patches.
The Android system log reports the following (while actively casting):
06-16 17:44:24.842 1095-1150/? I/DreamManagerService: Entering dreamland.
06-16 17:44:24.846 1095-1145/? I/DreamController: Starting dream: name=ComponentInfo{com.android.systemui/com.android.systemui.doze.DozeService}, isTest=false, canDoze=true, userId=0
At which point (after a few seconds delay) my Chromecast onConnectionSuspended()
method is called, with a value of CAUSE_NETWORK_LOST
. Which would of course be because Doze mode has turned off the wifi.
Did the 'June 5, 2017' security updates for Android 7.1.2 cause Android to start ignoring the battery optimization whitelist (i.e. the thing that's meant to let an app disable Doze mode)?
And if so, how can an app now programmatically disable Doze mode if it has a use-case that requires the CPU and wifi be kept continuously active?
Edit
Here's a minimal example project that demonstrates the issue (at least on my Google Pixel):
https://github.com/adam-roth/droid-doze-test
This is the result I get, running the test on my Pixel:
来源:https://stackoverflow.com/questions/44593369/do-the-latest-android-updates-disable-the-battery-optimization-whitelist