Why does my AlarmManager trigger instantly? - android

I want the AlarmManager to repeat a task at scheduled time (weekly)
I used the following code:
for (Integer day : daysList) {
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, PersonalUtils.getDigitalWeek(day));
c.set(Calendar.HOUR_OF_DAY, task.getHour());
c.set(Calendar.MINUTE, task.getMinute());
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
intent.putExtra("id", task.getId());
PendingIntent operation = PendingIntent.getService(
getApplicationContext(), requestCode, intent, 0);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(),
AlarmManager.INTERVAL_DAY * 7, operation);
}
However the alarm it triggered prematurely.
For example: Assuming that it is 18:30 Wed now. I setup a task which should be triggered at 17:30 Tue next week but instead the alarm is triggered immediately
Can anybody tell me why?

You are trying to do an inexact alarm, which only allows for a few specific constants, INTERVAL_DAY, INTERVAL_FIFTEEN_MINUTES, etc. See Android Docs for more. Those constants are only supposed to be used for InexactRepeatingAlarms, but I see your doing a RepeatingAlarm.
You have a couple of choices, you can either set the alarm to trigger in exactly 1 week, or you can set it to trigger every day inexactly and only pay attention to it if the alarm occurs during the 7th day. To trigger exactly every 7 days from now, try this:
final long WEEK_IN_MILLIS= 604800000;
alarm.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis()+WEEK_IN_MILLIS,
WEEK_IN_MILLIS, operation);
Note that I set it to first trigger in 1 week, then repeat every week after that. That should work for you.

Related

How to set alarm for any specific day in a week

I am creating a alarm clock application for android. I am facing certain issue Such as :-0
After searching entire internet. I didn't get any good solution.
How to set repeat alarm for user selected days? For example if user selected to set an alarm at Sunday and Monday on 9:00 AM. I tried certain solution from the internet but nothing works for me. This is my code
calendar = Calendar.getInstance();
Intent intent = new Intent(context,BROADCAST_RECEIVER.class);
calendar.set(Calendar.DAY_OF_WEEK, WEEK_DAY);
calendar.set(Calendar.HOUR_OF_DAY,HOURS);
calendar.set(Calendar.MINUTE, MIN);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
PendingIntent pendingIntent = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getBroadcast(context, sharedPref.GET_ALARM_CODE(), intent, PendingIntent.FLAG_MUTABLE);
}
else {
pendingIntent = PendingIntent.getBroadcast(context, sharedPref.GET_ALARM_CODE(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), (DateUtils.DAY_IN_MILLIS)*7 , pendingIntent);
dbHelper.alarmDao().AddAlarm(new AlarmDatabase(calendar.getTimeInMillis(),AM_PM,DAYS,sharedPref.GET_ALARM_CODE(),"ON",notes,alarm_time,need_to_show));
}
How to calculate specific time in milliseconds for the user selected days ? I used this code.
calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, WEEK_DAY);
calendar.set(Calendar.HOUR_OF_DAY,calender_hours);
calendar.set(Calendar.MINUTE, calender_minutes);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
By the time in am writing this question it's Friday here. I to calculate time from Friday 6:31 to Saturday 6:31 in milliseconds but get 1660933800000 this much milliseconds. Which is equivalent to 461370.5 in hours.
How to know that user selected past time ? So we can set alarm for the next day according to user selected hour and minutes.
I am thinking about one approach to solve 1 problem. I don't know is this good or not. What if on broadcast receiver I took current alarm schedule from local database and set alarm for next day using setexact() ? For example user selected Monday and Wednesday. And when alarm trigger on Monday then in receiver I check next alarm schedule which is Wednesday and set alarm for Wednesday. And this cycle repeats. Is this good ?
Thanks in advance for help.

Setting Notification using AlarmManager by passing calendar.getTimeInMillis(),triggers notification instantly not at the time intended

I have followed the following link https://developer.android.com/training/scheduling/alarms.html.
RTC examples first one, to set an alarm for a specific time on all days. Even after following the same code, the alarm is not triggered at the time it is suppose to get triggered. Instead the notification gets triggered immediately after setting the time which is done with the help of a time picker. Following is my code snippet,
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, NotificationReceiver.class);
PendingIntent intentalarm = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,4);
calendar.set(Calendar.MINUTE, 30);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, intentalarm);
Instead of setRepeating I also tried setInexactRepeating but there was no luck.I would also like to add that when I changed the
calendar.getTimeInMillis() and used SystemClock.elapsedRealtime() + 120 * 1000 the alarm triggered exactly after 2 minutes from the time it was set.
But when calendar.getTimeInMillis() is being used the intended working does not happen instead immediate triggering occurs.
Would be indeed very helpful if anyone can help me out find a solution.Only for a note, I could learn if alarm is set before current device time the alarm would be triggered immediately but that is not the case here.
NotificationReceiver.class is working fine as it is generated and appears on the title. But the time it appears is the cause of concern.
You are using both setTimeInMillis and hourofday and minute.
If you want your alarm to be triggered at 4:30 just add hourofday and minute.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,4);
calendar.set(Calendar.MINUTE, 30);`
I could Identify the issue I was facing. I was using a TimePicker with 24 hour format. But I used SimpleDateFormat "hh:mm". What 'h' stands for is as follows "h->Hour in am/pm (1-12) ". So any alarm that I set at AM triggers correctly. When I set a time at PM since I had used 1-12 'h' format, alarm gets set for a AM time and since that time is already passed when compared to the device time the alarm/notification got triggered immediately.The right format to use was "HH:MM" where 'H' stands for "H->Hour in day (0-23)". This resolved my issue.
Checking the TimeinMillis on online epoch time converter helped me identify this issue.Once again thanks for helping me.

Notification shows not in exact time

I know that this topic is explained fairly well and there are a lot of tutorials. But maybe I'm too new in android to understand what I'm doing wrong.
I need to implement support of set of reminders. And notification should be shown exactly every Monday at 15 pm. I checked a lot of tutorials and similar questions on this site but anyway notification shows, somehow, randomly.
How do I test implementation:
Current time is 14:55
I set reminder on Monday at 15:00
And right after SAVE notification is shown.
Because of (just for example) I set repeat period in 20 sec, this notification is shown again and again with delay of 20 sec. But current time is still between 14:55 and 15:00.
And my task is to run notification at 15:00 or a liitle later. But not before.
set repeating notification
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, NotifyService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, (int) reminder.id, intent, 0);
final Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_WEEK, 2);
calendar.set(Calendar.HOUR_OF_DAY, reminder.time.hour);
calendar.set(Calendar.MINUTE, reminder.time.minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,
Calendar.getInstance().getTimeInMillis(), 20000, pendingIntent);
BTW
my min SDK version is 7, so I cannot use methods like setExact()
android version on tested device is 4.4.2
Thanks
When you set the alarm you set it with Calendar.getInstance().getTimeInMillis() instead of calendar.getTimeInMillis(). Simple bug ;).
Basically setting the alarm to 'now' every time, ignoring your calendar object.

android-can't run a code one a day

This is a code that i'm using for running a service once a day .
the problem is this , after 24h , the service keeps calling every 10 to 15 min .
Intent myIntent = new Intent(this, MyService.class);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.HOUR, 24);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 86400, pendingIntent);
I think I'm using a bad code .Could you give me a better code for runnig a service once or twice a day
thanks you
The interval parameter to setRepeating represents millis. It should be 86400000 to get it right.
You are now programming an alarm to start first execution 24h past the current time, but with a period of 86400 millis (less than two minutes).
Morale of the story:
Always read the docs before using an API.
Use AlarmManager.INTERVAL_DAY instead of your own magic numbers

Android: set alarm to fire everyday except the weekends

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?

Categories

Resources