After some research, many other posts try to solve this question with the implementation of the following code:
Add to Manifest :
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Use this function to request optimization:
PowerManager pm = (PowerManager) context.getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName))
{
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + "YOUR_PACKAGE_NAME"));
context.startActivity(intent);
}
As you mentioned in the post, isIgnoringBatteryOptimizations will be true only in case 1. Appart from that, it looks like Google won't be very happy with this approach and your app may not be published.
I found out the following approach to work more conveniently:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P)
{
ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
Boolean isRestricted = am.isBackgroundRestricted();
if(isRestricted)
{
// Show some message to the user that app won't work in background and needs to change settings
//... (implement dialog)
// When user clicks 'Ok' or 'Go to settings', then:
openBatterySettings();
}
}
private void openBatterySettings()
{
Intent intent = new Intent();
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
getContext().startActivity(intent);
}
This code works if you want to find case 3. Please take into consideration that case 3 is only relevant in Android API 28 and onwards, apps shouldn't be killed in the background when API < 28, there's no case 3 when API < 28.
Hope it helps.