检查应用程序是否启用了电池优化

60

Android 6和7具有一些电源优化(Doze模式),当设备未使用时限制应用程序的网络连接。

用户可以在电池设置中为任何应用程序禁用优化模式:

android settings screenshot

是否可以检查我的应用程序是否启用了优化?我需要要求用户禁用优化以获得更好的应用程序功能,但我不知道如何在程序中检查它。


3
请注意,除非应用程序符合以下要求:https://developer.android.com/training/monitoring-device-state/doze-standby#whitelisting-cases,否则不允许要求用户将您的应用程序加入白名单。 - Prasad Pawar
4个回答

66

在 manifest 文件中添加这个权限。

<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);
        }
    }

28
是的,它完美地运作了 :D 但唯一的问题是该应用将被 playstore 拒绝,并且您将失去所有业务! - Rohit TP
4
请问你能否详细解释一下为什么在应用程序中添加这个检查会导致它成为PlayStore拒绝的候选项? - sud007
15
"@sud007 'ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS'是一个危险的权限。谷歌不喜欢应用程序在其代码中使用这个权限(https://developer.android.com/training/monitoring-device-state/doze-standby)。如果我们添加了这个权限和操作,就会有一些风险,因为这样做允许应用程序直接显示一个安卓弹出窗口,要求用户关闭该应用程序的电池优化。 相反,您应该使用“ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS”,它可以将用户带到应用程序列表,然后用户需要手动搜索您的应用并禁用电池优化。" - Rohit TP
1
@RohitTP 是的,伙计,我检查了所有有关此事的细节,并了解了其重要性,因此添加了我的第二条评论。无论如何,谢谢! :) - sud007
3
可能是金钱和裙带关系。 - Vivek
显示剩余6条评论

42

如何使用 Kotlin 编写此代码

  1. 检查是否已启用优化
    /**
     * return true if in App's Battery settings "Not optimized" and false if "Optimizing battery use"
     */
    fun isIgnoringBatteryOptimizations(context: Context): Boolean {
        val pwrm = context.applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
        val name = context.applicationContext.packageName
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return pwrm.isIgnoringBatteryOptimizations(name)
        }
        return true
    }

检查是否启用了优化功能,打开优化的Activity
    fun checkBattery() {
        if (!isIgnoringBatteryOptimizations() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val name = resources.getString(R.string.app_name)
            Toast.makeText(applicationContext, "Battery optimization -> All apps -> $name -> Don't optimize", Toast.LENGTH_LONG).show()

            val intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
            startActivity(intent)
        }
    }

5
为什么要用“>= VERSION_CODES.LOLLIPOP_MR1”? ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS是在Android M中添加的。 - adriennoir
2
感谢分享完整的解决方案。运行得非常好! - sud007
你需要REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 权限才能让第二部分正常工作。 - lasec0203
正如lasec0203指出的那样,请在你的清单文件中添加<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />。 - Bharadwaj Giridhar
2
根据CommonsWare的说法,如果您想要使用ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,将用户直接引导到专门为您的应用程序和白名单而设的页面,您需要在清单中请求REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,但您不需要为此使用运行时权限代码。如果您想避免该权限,请改用ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS。因此,如果您使用上述答案,则无需REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限。 - Chaitanya Karmarkar

40

4
如果您想让用户翻转它,可以使用以下内容:https://developer.android.com/reference/android/provider/Settings.html#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS - FriendlyMikhail
1
这是否也适用于制造商修改的ROM,还是仅适用于Nexus/Pixel/A1版本? - bearlysophisticated
@EfiMK 我没有进行全面测试,但我可以确认 PowerManager.isIgnoringBatteryOptimizations() 方法在三星和华为设备上运行正常。我认为它适用于任何制造商的 ROM。 - bearlysophisticated

17

示例代码:

 PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
                    askIgnoreOptimization();
                } else {
                   // already ignoring battery optimization code here next you want to do
                }
            } else {
           // already ignoring battery optimization code here next you want to do
            }

声明静态变量

private static final int IGNORE_BATTERY_OPTIMIZATION_REQUEST = 1002;

显示电池优化对话框

 private void askIgnoreOptimization() {

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, IGNORE_BATTERY_OPTIMIZATION_REQUEST);
        } else {
            openNextActivity();
        }
    }
也需要在清单文件中添加权限,即如下所示。
<uses-permission  android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

也许这段代码对您有帮助!


@yogesh 如何知道他是否已经点击了允许/拒绝,以及在哪里? - Ramesh
@Ramesh,你可以在onActivityResult上进行验证。 - Yogesh Rathi
@YogeshRathi 我正在使用React Native开发应用程序。因此,在我启动Activity的askIgnoreOptimization()方法中,我需要返回布尔值。 - Ramesh
@Ramesh,你找到解决方案了吗?这正是我卡住的地方。 - Keselme
@Ramesh,如果你还感兴趣的话,我认为我有一个解决方案,不需要AppState这个东西。让你的模块实现ActivityEventListener接口。然后将其添加为模块上下文的监听器。然后调用startActivityForResult并实现onActivityResult方法。在这里,您可以检查权限是否已授予,并通过Promise解决它。我相信它能够正常工作,尽管我仍在使用这种方法测试不同的场景。 - Keselme
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接