This is strange, what is the reason method setInexactRepeating trigger approximately at given time rather then exact time.
I need to trigger alarm on every day basis at one particular time, i have said
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// Set the alarm's trigger time to 8:30 a.m.
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
I have set time 8:30 am in the calendar, when i shift device day to next day, alarm get trigger immediately even before i shift device time to 8:30am.
What is happening here, why i can't make exact trigger using this api, if any of you have experience this, could you share your experience. Thanks!
According to documentation (here) there is text:
As described above, choosing the alarm type is often the first step in
creating an alarm. A further distinction is how precise you need your
alarm to be. For most apps, setInexactRepeating() is the right choice.
When you use this method, Android synchronizes multiple inexact
repeating alarms and fires them at the same time. This reduces the
drain on the battery.
For the rare app that has rigid time requirements—for example, the
alarm needs to fire precisely at 8:30 a.m., and every hour on the hour
thereafter—use setRepeating(). But you should avoid using exact alarms
if possible.
With setInexactRepeating(), you can't specify a custom interval the
way you can with setRepeating(). You have to use one of the interval
constants, such as INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY, and so on.
I hope it could help You bit. There is also small example for it in previous link I gave You.
Related
I need an alarm application for specific time of every hour. For example, if I set the alarm value at 25, the alarm will go off at 25th min of every hour.ie 11:25am, 12:25pm, 1:25pm, 2:25pm etc. Is it possible? or is there an application, preferably android that has such functionality?
yes, it is possible with repeating Alarms. you can set alarm to fire at exact time with setRepeating() and the alarm's interval set to every hour and RTC_WAKEUP alarm type(Wakes up the device to fire the pending intent at the specified time). there are some examples in the first link.
I have to call a service in every day on a particular time.obviously i had choose AlarmManager for waking up my service.and all working well other than AlarmManager triggering immediately when i set the past time.but it's working fine when i set time after current time.
For better clarification i will say an example.
WORKING ATTEMPT : Current time is 09.00 AM am setting schedule as
10.00 AM.And AlarmManager doing his job perfectly.
FAILURE ATTEMPT :Current time is 10.00 AM am setting schedule as
09.00 AM.And AlarmManager calls the services immediately.
Actually i need to invoke my service tomorrow 09.00 AM as the scheduled time is past.
I referred some query almost matching this one but it wasn't good enough.What i am doing wrong ?
My Code
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
myIntent.putExtra(ACTION, ACTION_SC_1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, REQUEST_CODE_SC_1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getBaseContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
Dont use alarm manager use GcmNetworkManager which was introduced in the last IO. It will work like a charm and you will have the ability to set in to inexact alarm so u wont need to wakeup the device. From the google IO site : Google Play Services has added the GCM Network Manager which functions mostly like JobScheduler, but extends to prior releases before Lollipop.
From the documentation
Like set(int, long, PendingIntent), except you can also supply a period at which the alarm will automatically repeat. This alarm continues repeating until explicitly removed with cancel(PendingIntent). If the stated trigger time is in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.
It is working intentionally like this.
As Bonatti said above, this is documented behaviour of the API when you set a time in the past.
You will need logic in your app to push out the alarm by 24hrs if it is already past 10am at the time when you want to set the alarm.
The easiest way to do this is probably to use the Calendar object as you have, then query
if (calendar.after(SystemClock.currentTimeMillis()) {
// Push alarm out til tomorrow.
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
If you need the alarm to be triggered at 9AM sharp, don't use setRepeating() as it will not launch at the exact time since Android KitKat (this is also documented, you should really read the docs).
Use Calendar to build the timestamp from your desired alarm time. Check if the result timestamp is smaller than the current timestamp System.currentTimeMillis(), in that case it's in the past so add 24 hours to it to schedule it for the next day.
Finally, use AlarmManager.set() on older versions or AlarmManager.setExact() on newer versions of Android to schedule your alarm. Once the alarm goes off, you can schedule the next one using the same technique.
I'm scheduling repeating alarms in order to execute service one a period of time.
// Set the alarm to start at approximately 24:05 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 24);
calendar.set(Calendar.MINUTE, 5);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, );
Some question about the implementation :
What happens if user delete the application (including the service), will something crash on the next alarm ?
Again if user delete the application, the alarms will continue running ? If so, how can I cancel any repeating alarms ?
Where/When is the best place/time to initiate the repeating alarms ? Should I wrap it with "only once" block ?
I'm not completely sure but I can give answers for your questions;
1- If user deletes your application and service, I think anything crash on the next alarm because I think your application is running on the service. (if there is no service, alarm does not works i think)
2- If user deletes your app, alarm will works but if service doesn't works, alarm does not works.
3- I think there is some options for repeating alarms and user can select one of this options.
I want to execute some task (e.g. show notification), by schedule, e.g.: 10:00 every day AND 11:00 every monday and etc., I can't use AlarmManager, because the time interval between tasks is different and I can't run task every N second. Can I specify a few tasks for AlarmManager? How I can do it and what I should use?
I can't use AlarmManager, because the time interval between tasks is different
Yes, you can.
One option is to use different alarms for different tasks. In your example, you would have one alarm for "10:00 every day" and a separate alarm for "11:00 every Monday".
Another option is to use a single alarm for whatever comes next, where it then does whatever your business logic is (e.g., remind the user of the event) and then schedules the next alarm for the next thing to occur. For example, using my time zone, it is 07:45 on a Saturday right now. Your app would have an AlarmManager alarm to get control at 10:00 ("10:00 every day"). When that alarm is invoked, it would then schedule an AlarmManager alarm for 10:00 Sunday ("10:00 every day"). 10:00 on Sunday, it would then schedule an alarm for 10:00 Monday ("10:00 every day"). 10:00 on Monday, it would then schedule an alarm for 11:00 Monday ("11:00 every monday"). 11:00 on Monday, it would then schedule an alarm for 10:00 Tuesday. And so on.
If there are only a couple of rules, I would go with the first option. If there could be N possible rules, I would go with the second option, so as not to flood AlarmManager.
Can I specify a few tasks for AlarmManager?
Yes. Make sure that the PendingIntent objects are distinct. The easiest way to do that is to use unique values for the requestCode parameter to PendingIntent factory methods like getBroadcast().
How to set up a repeating alarm to fire immediately when a Button is pressed and repeat itself in every 4 hrs.?
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),
4*60*60*1000, alarmIntent);
Repeats itself but doesnt start immediately when a Button is pressed. it takes 5 mins to fire.
What am I doing wrong here?
I changed the code as below and the alarm is fired immediately
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, AlarmManager.INTERVAL_FIFTEEN_MINUTES, 4*60*60*1000, alarmIntent);
but it doesn't repeat every 4 hrs. How can I make the alarm repeat every 4 hrs?
Use setRepeating instead of setInexactRepeating.
Use setInexactRepeating when you want you alarm to fire around the specified time but you don't really need it to trigger exactly at that time.
This method exist so that the Android Os can manage to fire all the alarms at the same time in order to save battery life.
Take a look at this question, it might help you.
Quoting the accepted answer:
you should schedule alarm with AlarmManager.setExact() and then when alarm triggers do it again for next week and so on every week.
That's probably because you are using setInexactRepeating.
From google's documentation for setInexactRepeating:
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
setRepeating(int, long, long, PendingIntent) instead.
Try:
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+2*1000,
4*60*60*1000, alarmIntent);
and check if it fires at least after 2 secs ..
Not sure if it will solve your problem, but might lead you to a workaround.