I am developing an app which needs to perform particular action on the exact time which user has set. For this i am using setExactAndAllowWhileIdle() method bec
you can whitelist your app from doze mode by ignoring battery optimizations..
Add permission
<uses-permission
android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
request whitelist your app
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);
}
}
Note: Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 15 minutes per app.
I've found the solution for my problem so, i am posting my own answer here which worked for me.
Using setAlarmClock() method has solved my problem. If you set alarm using setAlarmClock() method then this will not allow the system to go into doze mode before 1 hour of your alarm's time. I had tested this by manually forcing my device to go into doze mode after setting my alarm. Let me explain full scenario.
adb shell dumpsys deviceidle force-idle
It Shows
unable to enter into doze mode
Hence, i conclude that setAlarmClock() method prevents your device from entering to doze mode if there is a small amount of timestamp between current time and your alarm time. Otherwise if your device is already in doze mode then it will gets exit from doze mode before some time of your alarm so, your alarm works fine.
Updated code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(d.getTime(),pendingIntent),pendingIntent);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
alarmManager.setExact(AlarmManager.RTC, d.getTime(), pendingIntent);
else
alarmManager.set(AlarmManager.RTC, d.getTime(), pendingIntent);
Some addition to @MarGin's answer.
It's much easier for user to do all in one dialog but this violates the Google Play policy
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
startActivity(
Intent(
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
Uri.parse("package:$packageName")
)
)
}