13

I'm developing an app that should alert an user if is near a place. and of course have to do that also if the phone is in idle. With DOZE now I understood that I have to whitelist my app, and to do that I saw that I can start an intent with the action request thanks to Buddy's answer in this post

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

well this should be too easy...because google doesn't like this approach and if you do it, your app should be banned from the play store...no comment... Ok so the way should be to drive the user to the battery settings and manually add your app in the DOZE's white list...yes this should be a big wall to climb...anyway seems to be the only way...now the answer is: I Can use an intent to go to the power usage summary, in this way (thank you Chris):

Intent powerUsageIntent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
    ResolveInfo resolveInfo = getPackageManager().resolveActivity(powerUsageIntent, 0);
// check that the Battery app exists on this device
    if(resolveInfo != null){
        startActivity(powerUsageIntent);
    }  

But how to directly go at the list of app for choosing the battery optimization?

Thanks for any answer.

Community
  • 1
  • 1
Ast
  • 337
  • 1
  • 4
  • 17
  • As I understand, action Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS is what you need – Grimmy Jan 24 '17 at 17:53
  • 1
    Hi Grimmy, be careful with it, as I wrote google doesn't like this approach and if you do it, your app should be banned from the play store...read this tread: http://stackoverflow.com/questions/33114063/how-do-i-properly-fire-action-request-ignore-battery-optimizations-intent – Ast Jan 24 '17 at 18:01
  • According to that thread Google can ban your app if it requests android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission. But you don't need it for Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS action, which will show list of apps for choosing battery optimization – Grimmy Jan 25 '17 at 10:35
  • So you say that if I does not put in the manifest file the request, for google is ok? – Ast Jan 25 '17 at 10:57
  • This is what was mentioned in the thread which you've send me – Grimmy Jan 25 '17 at 11:42
  • yes, you're right, reading careful all the comments of the post seems that this way can be good, thank you @Grimmy. – Ast Jan 25 '17 at 11:48
  • I've add it as an answer, so other people can find it easily then in comments – Grimmy Jan 25 '17 at 13:36
  • @Grimmy Google does NOT ban apps with `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS `. Google recommends this. See **https://developer.android.com/training/monitoring-device-state/doze-standby** – IgorGanapolsky Apr 12 '20 at 18:27

3 Answers3

33

To open list of apps for choosing battery optimization you can use this code sample:

private void openPowerSettings(Context context) {
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
    context.startActivity(intent);
}

It doesn't need to have <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> permission, so it should be ok to publish it to Google Play (for details please check this thread and comments to this question).

NOTE

Adding this line

intent.setData(Uri.parse("package:" + mContext.getPackageName()));

will cause crash "Fatal Exception: android.content.ActivityNotFoundException No Activity found to handle Intent { act=android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS dat=package:io.demo.example }". User has to find the app in the list, it seems no way to jump directly to our app.

thanhbinh84
  • 17,876
  • 6
  • 62
  • 69
Grimmy
  • 2,041
  • 1
  • 17
  • 26
  • 3
    I got an error Fatal Exception: android.content.ActivityNotFoundException No Activity found to handle Intent { act=android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS dat=package:io.demo.example } – Ahmad Shahwaiz Dec 18 '17 at 07:28
  • 1
    I am also getting same exception. Any solution till now? – ParikshitSinghTomar Feb 14 '18 at 07:03
  • 1
    We can directly open the android's native popup asking for disabling battery optimization, Check the below link. It is working for me. https://stackoverflow.com/a/33114136/3497972 – akashzincle Sep 26 '19 at 09:51
  • @akashzincle deprecated and anti safe pattern – user924 Jan 13 '23 at 13:38
2

This is what I use:

manifest:

    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.annotation.RequiresPermission
import androidx.core.content.ContextCompat

object PowerSaverHelper {
    enum class WhiteListedInBatteryOptimizations {
        WHITE_LISTED, NOT_WHITE_LISTED, ERROR_GETTING_STATE, IRRELEVANT_OLD_ANDROID_API
    }

    fun getIfAppIsWhiteListedFromBatteryOptimizations(context: Context, packageName: String = context.packageName): WhiteListedInBatteryOptimizations {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return WhiteListedInBatteryOptimizations.IRRELEVANT_OLD_ANDROID_API
        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager?
                ?: return WhiteListedInBatteryOptimizations.ERROR_GETTING_STATE
        return if (pm.isIgnoringBatteryOptimizations(packageName)) WhiteListedInBatteryOptimizations.WHITE_LISTED else WhiteListedInBatteryOptimizations.NOT_WHITE_LISTED
    }

    //@TargetApi(VERSION_CODES.M)
    @SuppressLint("BatteryLife", "InlinedApi")
    @RequiresPermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    fun prepareIntentForWhiteListingOfBatteryOptimization(context: Context, packageName: String = context.packageName, alsoWhenWhiteListed: Boolean = false): Intent? {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
            return null
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) == PackageManager.PERMISSION_DENIED)
            return null
        val appIsWhiteListedFromPowerSave: WhiteListedInBatteryOptimizations = getIfAppIsWhiteListedFromBatteryOptimizations(context, packageName)
        var intent: Intent? = null
        when (appIsWhiteListedFromPowerSave) {
            WhiteListedInBatteryOptimizations.WHITE_LISTED -> if (alsoWhenWhiteListed) intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
            WhiteListedInBatteryOptimizations.NOT_WHITE_LISTED -> intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).setData(Uri.parse("package:$packageName"))
            WhiteListedInBatteryOptimizations.ERROR_GETTING_STATE, WhiteListedInBatteryOptimizations.IRRELEVANT_OLD_ANDROID_API -> {
            }
        }
        return intent
    }
}

Example:

PowerSaverHelper.prepareIntentForWhiteListingOfBatteryOptimization(this)?.let { startActivity(it) }

android developer
  • 114,585
  • 152
  • 739
  • 1,270
1

Try the below code to open Ignore Battery Optimization Settings page.

private void openPowerSettings() {
    startActivityForResult(new Intent(android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS), 0);
}

No extra permissions are required to be added to the manifest file.

Hemant Aggarwal
  • 849
  • 1
  • 7
  • 13