Alarm manager not triggering alarms at exact time in android
Asked Answered
A

2

5

I scheduled alarm using Calendar class as below

Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY,1);
cal.getTimeInMillis();  
cal.set(Calendar.MINUTE,05);
long TriggerMillis = cal.getTimeInMillis();

AlarmManager aManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);      
aManager.set(AlarmManager.RTC_WAKEUP, TriggerMillis,pIntent);

where pIntent is an pending intent to proceed further when alarm triggers.

The event triggers with few seconds delay. Is that any problem using Calendar class for this task. Any suggestions?

TIA..

Ainslie answered 25/1, 2014 at 19:42 Comment(4)
What is pIntent? Is it a PendingIntent for a BroadcastReceiver?Fadein
Are you targetting API level 19? If so, it's by design. Alarm time won't be exact.Crumley
@Fadein pIntent is a pendingIntent to launch a service.Ainslie
@Tobor Yes I'm targeting API level 19. Is there any other way to overcome this problem?Ainslie
F
11

You have two issues:

  1. It is not reliable to use a _WAKEUP alarm with a service directly. The only reliable patterns involve WakefulBroadcastReceiver, my WakefulIntentService, or something along those lines, where the PendingIntent will be to a BroadcastReceiver.

  2. If your android:targetSdkVersion is 19 or higher, and you are running on an API Level 19+ device, set() is inexact. Ideally, you allow it to be inexact, or perhaps use setWindow() to control how off it will be, to minimize the power hit of your alarm event. If it absolutely has to occur at a precise moment, you will need to use setExact(). Since setWindow() and setExact() are new to API Level 19, you will need to fall back to set() on older devices, by examining Build.VERSION.SDK_INT and branching accordingly.

Fadein answered 25/1, 2014 at 20:42 Comment(2)
Is it possible to schedule repetitive future task at exact time for API 19+ ? I am facing issue when application is not running in background and device is idle. Thank you.Dextral
@Manmohan: Not really. The closest that you can come is to use setExact() and "repeat" yourself (by calling setExact() again as part of processing the work from the earlier setExact()). However, on Android 6.0+, even with setExactAndAllowWhileIdle(), this is not very exact.Fadein
S
2

I think you should use the function

setExactAndAllowWhileIdle

For example:

AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() + 100, pendingIntent); // +100 is to set nearly to the current time

You have to know that this is not a repeating alarm, so at the end of your BroadcastReceiver you should set the next alarm.

Regards

Salish answered 20/1, 2020 at 14:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.