I am developing an application for Android Lollipop and KitKat devices. The application needs to call an API in every predefined interval (Based on the interval received from server). I am doing this using AlarmManager class.
But the problem is it works till some time then stops.
Say for example If I set to start the alarm at 08:00 AM with an interval of 30 minutes it works till 11:00AM (aprx) and then alarm doesn't trigger.
If I set a long interval (eg : 8 hours from current time, still same issue happens, not reiggering even once )
Code
public void setRepeatedAlarm(Context context, int requestCode, long next, long interval, Intent intent) {
PendingIntent sender = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, next, interval, sender);
}
Function calling
AlarmHandleManager.get().setRepeatedAlarm(this, Constants.SchedulerRequestCodes.UPLOAD_LOG, date.getTime(), AlarmManager.INTERVAL_DAY, intent);
Let me know if any one can figure out the issue.
Have seen a bug reported in lollipop in Google bug tracker, If that is the case let me know if there is any alternative solution for this.
i don't think it's a bug since it's already mentioned in the official documentation
Note: As of API 19, all repeating alarms are inexact. Because this method has been available since API 3, your application can safely call it and be assured that it will get similar behavior on both current and older versions of Android.
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
Note: Beginning with API 19 (Build.VERSION_CODES.KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, android.app.PendingIntent) and setExact(int, long, android.app.PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
Related
If the following line of code is used, the Alarm is triggered immediately by AlarmManager, which is normal since Android documentation states that if an Alarm is set in the past it will be triggered immediately.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60*60*24*1000, alarmIntent);
Meanwhile, by setting it to trigger 1 minute later, using the code here after adding +60*1000 to System.currentTimeMillis(), the Alarm will not be triggered 1 minute later, as it should (actually the Alarm will never be triggered, even after waiting for 10 additional minutes - perhaps it will the day after, when repeating, but I have not tested this yet).
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+60*1000, 60*60*24*1000, alarmIntent);
Depending on your API level.
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS
will shift alarms in order to minimize wakeups and battery use. There
are new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent). Applications whose
targetSdkVersion is earlier than API 19 will continue to see the
previous behavior in which all alarms are delivered exactly when
requested.
https://developer.android.com/reference/android/app/AlarmManager.html
I have written an android daily-repeating alarm app using AlarmManager class.
The app was tested on a bunch of test devices running on android 4.2 - 5.0. Most of testing results were good except that of Sony Xperia Z2 and Xiaomi Mi 3 running on android 4.4.4:
Sony Xperia Z2: the alarm fired around 3 - 10 minutes later than the scheduled time. (A 9:10AM alarm would fire at around 9:13 - 9:20AM)
Xiaomi Mi 3: a regular 3 minute delay could be observed.
Below is the code snippet of setting alarm:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
// if scheduled time < current time, add 1 day
if (Calendar.getInstance().compareTo(calendar) == 1) {
calendar.add(Calendar.DATE, 1);
}
int alarmIntentId = 0;
int flag = PendingIntent.FLAG_UPDATE_CURRENT;
long repeatInterval = AlarmManager.INTERVAL_DAY;
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, alarmIntentId, intent, flag);
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), repeatInterval, alarmIntent);
Does anyone have ideas and solutions about this delay issue? There are couple of other alarm apps that works on Sony and Xiamo like "Timely". Any advises would be greatly appreciated.
The alarm delivery is inexact since API 19, use the setExact(int, long, PendingIntent) Method for an exact alarm and set this on every day new.
Have you note this?
http://developer.android.com/reference/android/app/AlarmManager.html
Summary:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
setRepeat Method:
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
Looking at the documentation here
I see the following line
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
So I guess by definition it is not exact.
Targeted API version changed to 18 and it has all worked.
I would like to make a delay(10 min) for user then after it, user can edit something.
to do this,I created a setAlarm function :
public void setAlarm(Context context,int user,int time) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, sef_time.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC, 1000*60*time , pi);
}
everything works fine, but my alarm manager has a delay.
for example:
setAlarm(.....,int 10);
It has a delay : 00:10:03 second or 00:10:10 second 00:10:20 second !
where is my wrong ?
As you can see here:
Beginning in API 19, the trigger time passed to this method is treated
as inexact: the alarm will not be delivered before this time, but may
be deferred and delivered some time later. The OS will use this policy
in order to "batch" alarms together across the entire system,
minimizing the number of times the device needs to "wake up" and
minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
With the new batching policy, delivery ordering guarantees are not as
strong as they were previously. If the application sets multiple
alarms, it is possible that these alarms' actual delivery ordering may
not match the order of their requested delivery times. If your
application has strong ordering requirements there are other APIs that
you can use to get the necessary behavior; see setWindow(int, long,
long, PendingIntent) and setExact(int, long, PendingIntent).
Applications whose targetSdkVersion is before API 19 will continue to
get the previous alarm behavior: all of their scheduled alarms will be
treated as exact.
If it's very important that the alarm be exact, use setExact (When the device's SDK is 19 or above).
The easiest way to make system have a delay and then sound an alarm at the exact specified time is using setExact(), and the code can be something like this.
am.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + (time_you_want_to_delay_in_milliseconds) ,pi);
Background
I'm currently developing an application for Android which revolves around an alarm that goes of on an user specified time. My intent for it is that it will be used for waking people up in the morning (and the following morning - aka repeating alarm). When the alarm goes of it will call an Activity that has a couple of options (such as snooze). I've got all of this working but I'm running in to a problem.
Problem
I'm using AlarmManager to handle my alarm needs. There is however something curious going on with the class (in my opinion). There are two adviced ways to handle the setting of the alarm time. Namely setInexactRepeating and setRepeating. The problem with these functions are:
setInexactRepeating is not very accurate. My tests have shown that this gets approximately activated at the specified time, which the documentation indicates, all be it rather vaguely;
the alarm will not fire before this time, but there may be a delay of almost an entire alarm interval before the first invocation of the alarm.
My tests show there is usually something of a 5 minute delay. On this answer the user has an average delay of approximately 12 minutes. This won't do, of course, for a system that is supposed to wake people up at their specified times.
setRepeating does trigger at the specified time. The docs specify however that as of API 19 that all repeating alarms are inexact. Which is exactly what I don't want.
As of API 19, all repeating alarms are inexact. Because this method has been available since API 3, your application can safely call it and be assured that it will get similar behavior on both current and older versions of Android.
There is a setExact method, but this is a bit too specific. Aside from that it does not give me the option to have a certain interval (for repeating the alarm daily). Edit: After trying to go with setExact I found that this would require me to move up to API 19 (currently on 15), which is something I would like to avoid.
Question
Am I using the wrong class for this system? To me it seems like it should be a legit usage, but reading through the docs has left me wondering. Is there perhaps another class which is better suited for this system?
You can separate before API 19 and after API 19. While setting alarm for the first time:
if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), mondayIntent);
} else {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY * 7, mondayIntent);
}
When you catch the alarm:
if (Build.VERSION.SDK_INT >= 19) {
rescheduleAlarm();
}
You must set the alarm with
setexact
again in rescheduleAlarm.
Hope this helps.
I was ready through the documentation and i was having some questions about setReating and setInexactRepeating. I was reading some other posts, but i could't find an answere.
The documentation says for both:
Note: as of API 19, all repeating alarms are inexact.
Does is mean that both methods are exactly the same in api 19 and above? Also how inexact is inexact? And if there is any delay, what are the effects for the following alarm?
Thanking in advance.
As one can read at the end of the official documentation as of API 19 [and future versions] all calls to setRepeating() will delegate to setInexactRepeating() instead. So as of KitKat and upcoming versions both methods do the exact same thing.
The delay will not effect the following alarms refering to the official documentation.
Schedule a repeating alarm that has inexact trigger time requirements;
for example, an alarm that repeats every hour, but not necessarily at
the top of every hour. These alarms are more power-efficient than the
strict recurrences traditionally supplied by setRepeating(int, long,
long, PendingIntent), since the system can adjust alarms' delivery
times to cause them to fire simultaneously, avoiding waking the device
from sleep more than necessary.
Your alarm's first trigger will not be before the requested time, but
it might not occur for almost a full interval after that time. In
addition, while the overall period of the repeating alarm will be as
requested, the time between any two successive firings of the alarm
may vary. If your application demands very low jitter, use one-shot
alarms with an appropriate window instead; see setWindow(int, long,
long, PendingIntent) and setExact(int, long, PendingIntent).
As of API 19, all repeating alarms are inexact. Because this method
has been available since API 3, your application can safely call it
and be assured that it will get similar behavior on both current and
older versions of Android.