I have scheduled an alarm to trigger on every day 10 AM.
I am setting this alarm at 12 AM Monday.
If the alarm time is past then the alarm will be triggered immediately.
but for my requirement I don't want to trigger immediately. Is fine for me to trigger on next day 10 AM.
Below is my current code to set Alarm:
Calendar activeModeTime = Calendar.getInstance();
// activeModeTime.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE));
activeModeTime.set(Calendar.HOUR_OF_DAY,
mSharedPrefManager.getActiveStartHourPref());
activeModeTime.set(Calendar.MINUTE,
Constants.DEFAULT_ACTIVE_START_MINUTE);
activeModeTime.set(Calendar.SECOND,
Constants.ALL_START_END_DEFAULT_SECOND);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
activeModeTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
getActiveModeAlarmPendingIntent());
how do I achieve this.
Check if the time that you've set is in the past and if it is then add 24 hrs to your trigger time.
if(activeModeTime < System.currentTimeMillis()){
activeModeTime += AlarmManager.INTERVAL_DAY;
}
write interval instead of REPEATING_INTERVAL.
For above example of 10 AM you need to write AlarmManager.INTERVAL_DAY instead of REPEATING_INTERVAL in below code.
if(Calendar.getInstance().getTimeInMillis()>=calendar.getTimeInMillis()){
timeInMillis = calendar.getTimeInMillis() + REPEATING_INTERVAL;
}else {
timeInMillis = calendar.getTimeInMillis();
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeInMillis,REPEATING_INTERVAL, pendingIntent);
Related
I have had several frustrations with setting alarms in Android. I have tried setting repeating/non-repeating alarms and exact/inexact alarms but it does not matter, if the alarm is ever set for a time in the past, it executes as soon as it is set. I have tested this as far back as setting an alarm for 5 hours in the past and is still executes immediately.
For example:
The time is 7 AM and I set an alarm to execute at 2 AM. This is obviously meant for the next time the clock reads 2:00 AM but it does not matter, the alarm goes off at 7 AM, right after it is set.
The code below should select a random time between 1:00 AM and 3:59 AM to set/execute the alarm for the next calendar day and then the logic circles back around to set itself again after execution. The alarm will execute repeatedly, forever.
int randomHour = new Random().nextInt((3 - 1) + 1) + 1;
int randomMinute = new Random().nextInt((59 - 1) + 1) + 1;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, randomHour);
calendar.set(Calendar.MINUTE, randomMinute);
calendar.set(Calendar.SECOND, 0);
calendar.add(Calendar.DAY_OF_MONTH, 1);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Questions:
At what point does Android stop executing alarms in the past?
Is there any way to stop this?
"This is obviously meant for the next time" Does not work for computers, they will do exactly what you tell them to do.
calendar.getTimeInMillis() returns the number of milliseconds since January 1, 1970 at 00:00:00 GMT. You need to specify not just the time but also the date that you want the alarm to go off. Instead you are always calling calendar.add(Calendar.DAY_OF_MONTH, 1); (the first day of the current month)
I want to set alarm for a specific time, I tried the code below. The problem is, most of the time alarm goes off within 10 seconds. I tried getting value of time in a toast and that seems to be perfectly fine.
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 1);
cal.set(Calendar.MINUTE, 54);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
long futureInMillis = SystemClock.elapsedRealtime() + delay;
long time = cal.getTimeInMillis()-(System.currentTimeMillis());
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, (1000*60*60*24) , pendingIntent);
Toast.makeText(context, "alarm set for" + time, Toast.LENGTH_SHORT).show();
I also tried,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, pendingIntent);
also,
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 24*60*60*1000, pendingIntent);
and,
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
As I understand your question("I want to set alarm for a specific time"), you want the alarm to sound at--lets say 10 AM tomorrow. However, your code seems to be in contradiction to this statement, because you are calculating a time difference:
long time = cal.getTimeInMillis()-(System.currentTimeMillis());
You may also be experiencing an issue the AlarmManager has by with the setRepeating() method. The Android documentation says:
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, if you do want to set an alarm for a specific time (and not a time difference) just try this:
long time = cal.getTimeInMillis();
You might also consider changing to the setExact() method and creating code to repeat as needed (there are examples on the Internet).
Link to Android documentation:
https://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int,%20long,%20long,%20android.app.PendingIntent)
I am trying to execute a background process on my android app every day at around 09h10 am. This works fine, but problem is after the first alarm has been fired at 09h10 am, it gets re-fired after 10 - 20 minutes throughout the day. I just want it to fire once a day, and only at that specified time. My code that sets the alarm manager is below:
PendingIntent reviewsPendingIntent = PendingIntent.getBroadcast(this,0,new Intent(this,ReviewReceiver.class),0);
AlarmManager alarmManager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());
Calendar cal = new GregorianCalendar();
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 10);
cal.set(Calendar.SECOND, 10);
cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
long interval = 6000*1440;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),interval,reviewsPendingIntent);
I have set the interval to 8640000 which is a day(I believe) if not, please advise accordingly. Thank you
1000ms*60s*60m*24h = 86400000 so You missed one 0
You can use
PendingIntent reviewsPendingIntent = PendingIntent.getBroadcast(this,0,new Intent(this,ReviewReceiver.class),PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),AlarmManager.INTERVAL_DAY,reviewsPendingIntent);
FLAG_CANCEL_CURRENT will prevent the alarm to be set multiple times
AlarmManager.INTERVAL_DAY = 1000 * 60 * 60 * 24
If you keep having some delay, it's because the sleep function is not precise. It's around the time you have set. Try with setExact and reschedule every day, doing the math by hand (initialTime + dayPassed * millsInADay) to have the best approximation.
If what Lindus has posted worked though, just forget it :) but I think that you'll have the same problem.
Im trying to set and run an alarm that run every hour, and is set by a few variables so as it will not run instantly, if the time is greater then the 58th minute
The idea is to set it # X hour and 58 minute, so it will run every hour, at the given minute(58).
Calendar calCurrent = Calendar.getInstance();
int time = 58 ;
Calendar calx = Calendar.getInstance();
calx.set(Calendar.MINUTE, time);
calx.set(Calendar.SECOND, 5);
if (calCurrent.get(Calendar.MINUTE) > time) {
calx.add(Calendar.HOUR, +1);
}
System.out.println("Alarm is set to - " + calx.get(Calendar.HOUR)+":"+
calx.get(Calendar.MINUTE));
alarmSwap = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmSwap.setRepeating(AlarmManager.RTC_WAKEUP,
calx.getTimeInMillis(), 60 * 60 * 1000, pintent);
The code works and runs correctly for the 1st instance, then the alarm will for some reason run # 0 minute the following hour.
Timeline looks like
1:23 - Repeating Alarm Set for 1:58 (1 hour intervals)
1:58 - alarm is triggered
3:00 - alarm is triggered
I have no idea why this alarm is being triggered # :00 for the last alarm. It is not being called from anywhere else.
Any help is greatly appreciated.
All alarms are resetting after the hour clocks over the hour-
Calendar calnew = Calendar.getInstance(); calnew.add(Calendar.SECOND, +5);
alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, calnew.getTimeInMillis(),900000 , pintent);
Timeline-
1:20 triggered
1:35 triggered
1:50 triggered
2:00 triggered
2:15 triggered
2:30 triggered
From android documentation.
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.
repeating alarms are not exact after API 19. This improves androids performance as android groups alarms which are at close interval and wakes system once and finishes all alarms(from other applications also).
If you really want exact alarms the you will have to set normal one time alarm, and then set alarm again in first alarm's call.
Try this code to repeat alarm every hour
alarmSwap.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
calx.getTimeInMillis(),
AlarmManager.INTERVAL_HOUR, pintent);
Hope this will help.You can ask if you have any further queries.
This worked for me to trigger alarm after every 1hour
alarmmgr = (AlarmManager) getSystemService(ALARM_SERVICE);
long interval = 60 * 60 * 1000; // 1 hour
xassert alarmmgr != null;
alarmmgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
I have read lots of articles, however I did not find/or just missed an answer on my specific quiestion, it is strange cause I think I am trying to implement a common case.
Well, what I whant is to set alarm to fire everyday except the weekends, so from monday-friday at some specific time.
Currently I do next:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
Intent intent = creating an Intent here
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
as far as I understand next code will fire an alarm on the time I have specified and do it every day, because of AlarmManager.INTERVAL_DAY.
I thought about doing next to accomplish my task:
for(int i = 1; i < 6; i++) {
calendar.add(Calendar.DAY_OF_WEEK, i);
}
But I am not sure, about the correctness of this logic.
Can you please
1. correct me, if I missed something
2. suggest some proper solution or just your thoughts to accomplish my task
Update:
Well, I have thought about next:
what if I
calendar.set(Calendar.DAY_OF_WEEK, 1);
and then
am.setRepeating(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 5, pendingIntent);
so as a result I will be setting initial day to Monday and repeat it 5 times, so Monday-Friday, no matter what is the current date, when user is setting an alarm, is it correct or I am missing smth?
Btw, how can I update setRepeating to set it to repeat every week, not only one?
Update1:
I guess I understood my error, by using the above code, I will do some strange things, so the init day is Monday, however the repeat interval is once in 5 days, not every day from Monday-Friday.
It seems that the only solution is to set
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
and in the fire handler, which I have specified in the Intent constructor, check the current day and avoid notification if it is Saturday or Sunday.
...
if(intent.getBooleanExtra(INTENT_NOTIFY, false) && !isWeekend())
showNotification();
...
private boolean isWeekend() {
Calendar calendar = Calendar.getInstance();
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
return (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY);
}
Btw, tell me please, I have set the alarm in repeat mode, for the first time it did fire, then I open emulator settings and manually move date to tomorrow and time back, but no alarm notification is fired, is it smth with emulator or I have some errors in code?