setExactAndAllowWhileIdle – is not exact as of developer reference –

Development issue/problem:

AlarmManager on API19 has a setExact() method to set the exact alarm.

Exact value -> If I set the alarm to 14:01, it will go off at 14:01.

API 23 – Marhsmwallow (6.0) has a new method setExactAndAllowWhileIdle(), but by reference it is not EXACT because it is triggered only every minute, and in low power mode only every 15 minutes.

That’s for sure! Every 15 minutes.

How do you get accurate alarms with AlarmManager 6.0?

If a user adds a reminder or appointment to the calendar and wants to be notified 10 minutes before the event, he/she must show a signal 10 minutes before the event. With setExactAndAllowWhileIdle() this seems impossible.

Reference:
http://developer.android.com/reference/android/app/AlarmManager.html#setExactAndAllowWhileIdle (int, lang, android.app.PendingIntent)

How can I solve this problem?

Solution 1:

How do you get accurate alarms with AlarmManager 6.0?

You can try setAlarmClock(), as this function is AFAIK independent of the doze mode. Otherwise, the AlarmManager is not the right option for you. Even if the application is on the white list, it does not help to optimize the battery because the behavior of the AlarmManager does not change according to the white list.

You can use GCMs because the priority message is to alert the user. Of course, this requires a network connection.

The only standalone solution I know – and am currently testing – is that the user adds his application to a battery optimization whitelist, and then uses an upstream service (to try and save the process), a ScheduledExecutorService (for synchronization) and a partial WakeLock (to keep the processor running). This is very damaging to the user’s battery.

Solution 2:

When you use setExactAndAllowWhileIdle() for a single alarm, it will sound at the exact time specified, even in the Doze Standby mode. I think so.

Problems start when you want to repeat the alarm to < 15 minutes (or set another alarm at the same time to < 15 minutes from the last), because it does not work in the Doze standby mode, where these alarms are forced for the next 15 minutes, or work at the start of maintenance in standby mode, which is first about ten minutes after 1 hour, then after 2 hours, then after 4 hours, and so on.

– EDIT –

As of today, 17. November, Diane Hackborn writes in the comments of this post:
The minimum time between alarms in standby mode will increase to 9 minutes at a relatively early stage (even on units in the current Marshmallow range).

But that doesn’t change anything fundamental.

Solution 3:

Here’s my conversation with Ian Lake on Google+!

setExactAndAllowWhileIdle() is accurate and should work.
The fifteen-minute time interval in the Java document is incorrect.

Give here a description of the image

Solution 4:

I have discovered that the best option so far is to use the SyncAdapter, which extends the AbstractThreadedSyncAdapter. I intend to run it automatically on the correct frequency:

ContentResolver.setSyncAutomatic (account, AUTHORITY, where);
ContentResolver.addPeriodicSync(account, AUTHORITY, settingsBundle, syncInterval) ;

Solution No 5:

I tried to create an automation system that works in the background. My frequency range was between 1 and 15 minutes. I didn’t want to use the service on the front line. When I looked at the name of the setExactAndAllowWhileIdle method, I thought, yes, it’s safe to work with point alarms and set the next one when it’s done.

However, I could not find a way to execute the code in drill mode when an alarm occurs for more than 15 minutes. Instead, I choose to start the service in the foreground when the snooze function is activated, and end the service in the foreground when the phone wakes up. The user will not see your message in the foreground when using the phone. I don’t really care about those who are dormant.

PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (intent.getAction().equals (android.os.action.DEVICE_IDLE_MODE_CHANGED)){
if (pm.isDeviceIdleMode()) {
//startAutomationForegroundService();
} else {
//stopAutomationForegroundService();
return;
}
AutomationReceiver.completeWakefulIntent(intent);
return;
}
}.

You must save the android.os.action.DEVICE_IDLE_MODE_CHANGED intent filter in your WakefulBroadcastReceiver. Prudence in the manifestation of this situation cannot help.

Good luck!

Related Tags:

setalarmclock android example,alarm manager vs work manager,alarm manager not working in oreo,how to set alarm in android programmatically,alarmmanager not working when app is killed,alarm manager not working when app closed,flag_wake_from_idle,setexactandallowwhileidle example,alarmclockinfo showintent,alarmmanager setexact,android detect doze mode,setexactandallowwhileidle not working in doze,setexactandallowwhileidle repeating,setalarmclock vs setexactandallowwhileidle,android alarmmanager example set repeating,alarmmanager setalarmclock

Leave a comment

Your email address will not be published. Required fields are marked *