Search code examples
androidoptimizationconfigurationbattery

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


I'm maintaining an app that is used by several companies, each of them with their own devices. One of them bought new tablets (Samsung A8 LTE with Android 11) and they started to have some problems. We realized that disabling the battery saving option the app works properly, so reading documentation I've discovered the existance of standby intervals or buckets for battery optimization. A temporal solution to this problem would be putting the app in a non restrictive bucket, but this is not recommended nor permitted, it's only a readable parameter by:

UsageStatsManager.getAppStandbyBucket()

The changes in each version are:

  • Android 9: App Standby Intervals introduced with 4 intervals or buckets.
  • Android 11: Restricted interval added.
  • Android 12: Restricted interval set as default for apps.

I need to do it manually whlie I find out the problem, probably something related to the app been put in background. Meanwhile I'm not sure how to do it: the battery configuration for each app has this 4 options. enter image description here

I'm not sure if 'Battery saver' (default) forces the app to use those buckets. I've read that you can look at the interval of an app in developers configuration, but I can't really find it. Besides, this behaviour only affects while the device is not charging (nevertheless that's not relevant).

My questions are: what's the relation between 'background settings' and 'buckets intervals'? If those configurations are not the same: could I set 'no restrictions' from code?


Solution

  • battery optimisation and usage bucket may be related or user may change option manually, so even oftenly used app may still be restricted... you can find out is it with below snippet

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

    and if it is you can request for disabling this 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);
    }
    

    also you will need a permission for this action

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

    note that some manufacturers are introducing own implementations of this feature, e.g. with some levels or scenarios, and may not respect/handle default Android params without providing own API for managing this (that was common few years ago on Samsungs and Xiaomis)