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 because this documentation says that android devices having android 6.0 or above has doze mode concept in which if devices remains idle for some times then it will enter into doze mode and doze mode restricts alarms. If i want to fire my alarm when device is into doze mode then i have setExactAndAllowWhileIdle()
method as documentation says. This documentation also contains manual way to enter device into doze mode for testing purpose. so, i am testing using that way but my alarm is not fired when device is into doze mode and when i stops doze mode via terminal command my past alarm will fires instantly.
So, my problem is that setExactAndAllowWhileIdle()
this method is not working in doze mode but it should have to work as said in documentation. I know limitation of this method that i can only fire one alarm per 9 minutes and i am following this rule. So, i can't understand where is the problem.
My Code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC, d.getTime(), 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);
Is it a method problem or i am doing it in a wrong way??
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With