为 Android 应用程序设置待机间隔的正确方法是什么?

What is the correct way to set a standby interval for an Android App?

我正在维护一个被多家公司使用的应用程序,每个公司都有自己的设备。其中一位购买了新平板电脑(三星 A8 LTE 与 Android 11),他们开始遇到一些问题。我们意识到禁用节电选项应用程序可以正常工作,因此阅读文档我发现了待机间隔或电池优化桶的存在。此问题的临时解决方案是将应用程序放入非限制性存储桶中,但这是 not recommended nor permitted,它只是一个可读参数:

UsageStatsManager.getAppStandbyBucket()

每个版本的变化是:

当我发现问题时,我需要手动执行此操作,可能是与应用程序相关的某些内容被置于后台。同时我不确定该怎么做:每个应用程序的电池配置都有这 4 个选项。

我不确定 'Battery saver'(默认)是否强制应用程序使用这些存储桶。我读过你可以在开发人员配置中查看应用程序的间隔,但我真的找不到它。此外,此行为仅在设备未充电时影响(尽管如此不相关)。

我的问题是:'background settings'和'buckets intervals'有什么关系?如果这些配置不相同:我可以从代码中设置 'no restrictions' 吗?

电池优化和使用桶可能相关,或者用户可能手动更改选项,因此即使是经常使用的应用程序也可能仍然受到限制...您可以通过下面的代码片段找到它

public static boolean isBatteryOptimisationEnabled(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        return pm != null && !pm.isIgnoringBatteryOptimizations(context.getPackageName());
    }
    return false;
}

如果是,您可以请求禁用此 feature/limitation

@SuppressLint("BatteryLife")
@TargetApi(23)
private static void gotoBatteryOptimisationSettings(Context context) {
    Intent intent = new Intent();
    String packageName = context.getPackageName();
    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    if (pm == null || 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);
}

您还需要获得此操作的许可

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

请注意,一些制造商正在引入自己对此功能的实现,例如具有某些级别或场景,并且可能不会 respect/handle 默认 Android 参数而不提供自己的 API 来管理它(几年前在三星和小米上很常见)

我需要在 Manifest 中获得新权限才能请求:

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

只是为了给 snachmsm 的答案添加一些知识,将代码添加到 C#(我应该说我在 Xamarin 中工作)。 :

        [TargetApi(Value = 23)] //Android 6 Marshmallow, introduce Doze para optimizar ahorro de batería
        [Android.Runtime.Register("ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS", ApiSince = 23)]    //TODO: investigar esta anotación con profundidad
        private static void goToBatteryOptimisationSettings(Context context)
        {
            Intent intent = new Intent();
            String packageName = context.PackageName;
            PowerManager pm = (PowerManager)context.GetSystemService(Context.PowerService);
            if (pm == null || pm.IsIgnoringBatteryOptimizations(packageName))
            {

                intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
            }
            else
            {
                intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
                intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
            }
            context.StartActivity(intent);
        }

    public static void deshabilitarAhorroEnergia(Context context)
    {
        if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
        {
            PowerManager pm = (PowerManager)context.GetSystemService(Context.PowerService);
            String packageName = context.PackageName;
            Intent intent = new Intent();
            if (pm == null || pm.IsIgnoringBatteryOptimizations(packageName))
            {
                intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
            }
            else
            {
                intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
                intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
            }
            context.StartActivity(intent);
        }
    }