1. 程式人生 > >Android 6.0的省電技術Doze作用影響以及避免方法

Android 6.0的省電技術Doze作用影響以及避免方法

從android 6.0開始,谷歌引入了兩項新的省電技術延長電池使用時間,分別是Doze(休眠)和App Standby(app待命模式),只要app是執行在6.0(api 23)及以上的系統,無論app編譯時是否使用的target=23,都會受到這兩種技術的限制。

理解什麼是Doze模式

如果裝置滿足

1、螢幕關閉;

2、沒有連線電源,

這樣持續一段時間後系統就會進入Doze模式,在Doze模式下,系統通過限制app訪問網路和其對CPU使用來達到省電的目的,app的網路訪問功能會被禁用,同時延時執行作業,非同步任務及標準鬧鐘事件。

同時,為了保證app的工作,系統會週期地退出Doze模式,以保證app完成那些被延時的任務,如下圖,這個狀態被稱作maintenance window(維護視窗)。且隨著系統處於Doze模式時間增長,進入maintenance window的頻率會降低。


Doze 模式下的限制

1、網路訪問功能被關閉

2、系統會忽略wake locks,即app無法持續佔有電源

3、標準鬧鐘 AlarmManager(包括setExact()和setWindow())都會被延時到下一個maintenance window才啟用

3.1 . 如果app仍需要在Doze時使鬧鐘生效,可以使用setAndAllowWhileIdle()或setExactAndAllowWhileIdle()

3.2 . 使用函式setAlarmClock()設定的鬧鐘在Doze時仍會生效,系統會在鬧鐘生效前推出Doze。

4、系統不會進行Wi-Fi掃描

5、系統不允許非同步Adapters執行

6、系統不允許JobScheduler執行

應用避免被省電優化解決方法

當然,應用有特殊需求才會這樣做,沒有必要的情況下不要這樣做,畢竟維護安卓良好生態,依靠你我他。

解決方法:設定應用為白名單

1、判斷應用是否已經為白名單

private boolean isIgnoringBatteryOptimizations(){
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
			String packageName = getPackageName();
			PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
			return pm.isIgnoringBatteryOptimizations(packageName);
		}
		return false;
	}

2、否的話,則提示使用者開啟
private final static int REQUEST_IGNORE_BATTERY_CODE = 1001;
    private void gotoSettingIgnoringBatteryOptimizations() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            try {
                Intent intent = new Intent();
                String packageName = getPackageName();
                intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + packageName));
                startActivityForResult(intent, REQUEST_IGNORE_BATTERY_CODE);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

可以在onActivityResult方法對結果進行處理
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK){
            if (requestCode == REQUEST_IGNORE_BATTERY_CODE) {
                Log.d("Hello World!","開啟省電模式成功");
            }
        }else if (resultCode == RESULT_CANCELED) {
            if (requestCode == REQUEST_IGNORE_BATTERY_CODE) {
                Toast.makeText(this, "請使用者開啟忽略電池優化~", Toast.LENGTH_LONG).show();
            }
        }
    }

記得加上許可權

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <!-- 白名單對話方塊許可權 -->


效果圖如下


在Doze時測試APP

1 . 需要一臺系統版本大於等於6.0(api23)的裝置

2 . 連線USB,執行被測app,保持app在活動狀態

3 . 關閉裝置螢幕

4 . 通過下面的adb命令強制系統進入Doze模式

$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step

第二個命令需要執行多次才能使系統進入idle狀態


畢。