web-dev-qa-db-ja.com

Dozeモードでアプリをホワイトリストに登録する方法Android 6.0

この質問は、今月末に最終リリースされるAndroid 6.0 Preview 3に関連しています。

Nexus 5「ハンマーヘッド」でGoogleのプレビュー3のAndroid 6.0でテストしています。

新しい機能は「ドーズモード」です。ネットワークが無効になって電話がスリープするときのディープスリープモードのようなもので、SMS、通話、または優先度の高いGCMメッセージのみがスリープモードを起動できます。しかし、WhatsAppのように-居眠りモードでは、タイマーに依存して2時間以上後にメッセージを受信します。ただし、「ホワイトリスト」と呼ばれる「最適化されていない」アプリのリストがあり、手動でアプリを追加できます。

わかりました。バッテリー設定のデバイスにある「ホワイトリストアプリリスト」にユーザーの介入なしにプログラムでアプリケーションを追加する方法を見つけたいです。

リフレクションを使用してそれを取得しようとすると、私は見つけました:

Android.os.IDeviceIdleController内にはメソッドがあります:

public abstract void addPowerSaveWhitelistApp(String packageNameOfApp)

しかし、これはインターフェースです...したがって、インターフェースのインスタンスを作成することはできません。

このインターフェイス、メソッド、または継承ツリーに関するドキュメントはまだありません。

たぶん、プログラムを使ってアプリを追加する可能性をどこで探すべきか、いくつかのアイデアをお持ちでしょうか?

メソッドもあります

public abstract boolean isPowerSaveWhitelistApp(String packageName)

どういうわけかアクセスできると思いますか?!ホワイトリストにアプリが存在するかどうかを確認し、おそらく最後にASKユーザーがホワイトリストに追加することを願っています。

だから私の質問は、あなたの誰かがより良い結果で何かを作ろうとしたのですか??私が立ち往生しているので、私はその行き止まりだと思います。

詳細: https://newcircle.com/s/post/1739/2015/06/12/diving-into-Android-m-doze

48
Fransis Q

許可を追加

<uses-permission 
Android:name="Android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

アプリのホワイトリストをリクエストする

 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Intent intent = new Intent();
            String packageName = getPackageName();
            PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            if (!pm.isIgnoringBatteryOptimizations(packageName)) {
                intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + packageName));
                startActivity(intent);
            }
        }
39
jefry jacky

Android Mプレビュー3でユーザーの操作なしに、バッテリー最適化(=居眠りモードのホワイトリストアプリケーション)を無効にすることはできません。

この方法でユーザーとのやり取りを行うことができます:

Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName))
    intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
else {
    intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intent.setData(Uri.parse("package:" + packageName));
}
context.startActivity(intent);
35
M66B

このヘルパークラスは、すべてのニーズをカバーすべきだと思います。

これを使用してOSにアプリのホワイトリスト登録を要求するには、prepareIntentForWhiteListingOfBatteryOptimizationを使用できます。 nullになった場合、それは必要ないか、使用できないことを意味します。他の関数を使用して、現在の状態のより良い状態を照会できます。

public class PowerSaverHelper {
    public enum PowerSaveState {
        ON, OFF, ERROR_GETTING_STATE, IRRELEVANT_OLD_Android_API
    }

    public enum WhiteListedInBatteryOptimizations {
        WHITE_LISTED, NOT_WHITE_LISTED, ERROR_GETTING_STATE, UNKNOWN_TOO_OLD_Android_API_FOR_CHECKING, IRRELEVANT_OLD_Android_API
    }

    public enum DozeState {
        NORMAL_INTERACTIVE, DOZE_TURNED_ON_IDLE, NORMAL_NON_INTERACTIVE, ERROR_GETTING_STATE, IRRELEVANT_OLD_Android_API, UNKNOWN_TOO_OLD_Android_API_FOR_CHECKING
    }

    @NonNull
    public static DozeState getDozeState(@NonNull Context context) {
        if (VERSION.SDK_INT < VERSION_CODES.Lollipop)
            return DozeState.IRRELEVANT_OLD_Android_API;
        if (VERSION.SDK_INT < VERSION_CODES.M) {
            return DozeState.UNKNOWN_TOO_OLD_Android_API_FOR_CHECKING;
        }
        final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (pm == null)
            return DozeState.ERROR_GETTING_STATE;
        return pm.isDeviceIdleMode() ? DozeState.DOZE_TURNED_ON_IDLE : pm.isInteractive() ? DozeState.NORMAL_INTERACTIVE : DozeState.NORMAL_NON_INTERACTIVE;
    }

    @NonNull
    public static PowerSaveState getPowerSaveState(@NonNull Context context) {
        if (VERSION.SDK_INT < VERSION_CODES.Lollipop)
            return PowerSaveState.IRRELEVANT_OLD_Android_API;
        final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (pm == null)
            return PowerSaveState.ERROR_GETTING_STATE;
        return pm.isPowerSaveMode() ? PowerSaveState.ON : PowerSaveState.OFF;
    }


    @NonNull
    public static WhiteListedInBatteryOptimizations getIfAppIsWhiteListedFromBatteryOptimizations(@NonNull Context context, @NonNull String packageName) {
        if (VERSION.SDK_INT < VERSION_CODES.Lollipop)
            return WhiteListedInBatteryOptimizations.IRRELEVANT_OLD_Android_API;
        if (VERSION.SDK_INT < VERSION_CODES.M)
            return WhiteListedInBatteryOptimizations.UNKNOWN_TOO_OLD_Android_API_FOR_CHECKING;
        final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (pm == null)
            return WhiteListedInBatteryOptimizations.ERROR_GETTING_STATE;
        return pm.isIgnoringBatteryOptimizations(packageName) ? WhiteListedInBatteryOptimizations.WHITE_LISTED : WhiteListedInBatteryOptimizations.NOT_WHITE_LISTED;
    }

    @TargetApi(VERSION_CODES.M)
    @RequiresPermission(permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    @Nullable
    public static Intent prepareIntentForWhiteListingOfBatteryOptimization(@NonNull Context context, @NonNull String packageName, boolean alsoWhenWhiteListed) {
        if (VERSION.SDK_INT < VERSION_CODES.Lollipop)
            return null;
        if (ContextCompat.checkSelfPermission(context, permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) == PackageManager.PERMISSION_DENIED)
            return null;
        final WhiteListedInBatteryOptimizations appIsWhiteListedFromPowerSave = getIfAppIsWhiteListedFromBatteryOptimizations(context, packageName);
        Intent intent = null;
        switch (appIsWhiteListedFromPowerSave) {
            case WHITE_LISTED:
                if (alsoWhenWhiteListed)
                    intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
                break;
            case NOT_WHITE_LISTED:
                intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).setData(Uri.parse("package:" + packageName));
                break;
            case ERROR_GETTING_STATE:
            case UNKNOWN_TOO_OLD_Android_API_FOR_CHECKING:
            case IRRELEVANT_OLD_Android_API:
            default:
                break;
        }
        return intent;
    }

    /**
     * registers a receiver to listen to power-save events. returns true iff succeeded to register the broadcastReceiver.
     */
    @TargetApi(VERSION_CODES.M)
    public static boolean registerPowerSaveReceiver(@NonNull Context context, @NonNull BroadcastReceiver receiver) {
        if (VERSION.SDK_INT < VERSION_CODES.M)
            return false;
        IntentFilter filter = new IntentFilter();
        filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
        context.registerReceiver(receiver, filter);
        return true;
    }


}
16

ホワイトリストはプログラムで実行できます。ホワイトリストに登録されたアプリケーションにデバイスを追加するには、アプリケーションから次のコマンドを実行します。

adb Shell dumpsys deviceidle whitelist +<package_name>

ホワイトリストに登録されたアプリケーションからデバイスを削除するには、アプリケーションから次のコマンドを実行します。

adb Shell dumpsys deviceidle whitelist -<package_name>
6
Shinoo Goyal

私が知る限り、Dozeからホワイトリストに登録することはできません。バッテリーの最適化を無視しても、居眠りは無効になりません。こちらをご覧ください: https://code.google.com/p/Android-developer-preview/issues/detail?id=2225 更新: Mのリリースビルドでは、バッテリーの最適化を無視するように要求できます。これにより、少なくともDozeモードでインターネットに通常アクセスできるようになります。

4
A.Sanchez.SD

更新

デバイスが再び静止し、画面を一定時間オフおよびオンにすると、DozeはPowerManager.WakeLock、AlarmManagerアラーム、およびGPS/Wi-FiにフルCPUおよびネットワーク制限を適用しますscans

詳細については、 ホワイトリストのユースケース をご覧ください。

以下の表は、バッテリー最適化の例外ホワイトリストを要求するか、そのリストに載っている許容可能なユースケースを示しています。一般的に、DozeまたはApp Standbyがアプリのコア機能を中断するか、アプリがGCMの高優先度メッセージを使用できない技術的な理由がない限り、アプリはホワイトリストに登録しないでください。

Android n開発者 言う

Dozeは、AlarmManageralarmsおよびtimersが管理するアクティビティに特に影響を与える可能性があります。 Android 5.1(APIレベル22)以下のアラームは、システムがDozeにあるときに起動しないためです。

Android 6.0(APIレベル23)では、setAndAllowWhileIdle()setExactAndAllowWhileIdle()の2つの新しいAlarmManagerメソッドが導入されています。これらの方法を使用すると、デバイスが居眠りしている場合でも起動するアラームを設定できます。

setAndAllowWhileIdle()setExactAndAllowWhileIdle()も、アプリごとに15分ごとに複数回アラームを発動することはできません。

Dozeおよびアプリスタンバイでのテスト

3
Amit Vaghela