Do the latest Android updates disable the battery optimization whitelist?

醉酒当歌 提交于 2019-12-10 13:58:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!