Why is my AlarmManager firing off instantly? - android

I'm trying to build an alarm application. I had the alarm working before and I was able to set the different times and the alarm would go off appropriately. I then changed the layout of the ChangeAlarmActivity to a TableLayout and now it won't work? I didn't touch the code. Here is how I set the alarm:
Intent alarmIntent = new Intent(ChangeAlarmActivity.this, AlarmReceiver.class);
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(ChangeAlarmActivity.this, (int)alarm.getID(),
alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
System.out.println("Alarm time: " + hour + ":" + min);
Calendar alarmCal = Calendar.getInstance();
//alarmCal.setTimeInMillis(System.currentTimeMillis());
alarmCal.set(Calendar.HOUR_OF_DAY, hour);
alarmCal.set(Calendar.MINUTE, min);
//alarmCal.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP,
alarmCal.getTimeInMillis(),
pendingAlarmIntent);

Possibly because your hour and minute are in the past.
Let's say that it is 16:07 hours (using 24 hour time) in your current time zone, and you execute this code with hour as 3 and min as 27. 03:27 was in the past, and hence the alarm fires immediately.
After making your two set() calls, see if the time is earlier than now, and if so, add() one day.

Related

Set alarm for several days

I'm working on alarm clock app. I've faced with one problem. I do not know how to set alarm for several days. I've already tried the code that is below but in log I saw this Wed Apr 06(didn't change any date so it should be nearest tuesday and friday). What do I do wrong? May be I should set alarm separately for every other day?
This is my code:
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY, Calendar.FRIDAY);
//calendar.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY);
Log.e("Point_1","Calendar " + calendar.getTime());
calendar.set(Calendar.HOUR_OF_DAY,timePicker.getCurrentHour());
calendar.set(Calendar.MINUTE,timePicker.getCurrentMinute());
Intent intent1 = new Intent(MyService_alarm.this,MyReceiver_Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService_alarm.this,intent.getIntExtra("Size", 1),intent1,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent);
Thank you.
That is because you are logging the time before setting the hour and minutes from the time picker,
your code si working fine but to display the time that was set to the Alarm in your log you have to move the Log.e to after you set the Calendar to the hour and minute from your picker so your code should look like this :
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY, Calendar.FRIDAY);
//calendar.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY);
calendar.set(Calendar.HOUR_OF_DAY,timePicker.getCurrentHour());
calendar.set(Calendar.MINUTE,timePicker.getCurrentMinute());
Log.e("Point_1","Calendar " + calendar.getTime());
Intent intent1 = new Intent(MyService_alarm.this,MyReceiver_Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService_alarm.this,intent.getIntExtra("Size", 1),intent1,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent);
Also since you are making an Alarm for several days it would be wise to save all the set alarms and to add a receiver to detect when the device has been booted since your alarms are cancelled on reboot and will need to be added again.
The line
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY, Calendar.FRIDAY);
is not correct. If you look at the documentation you will see that there is no such method.
By writing Calendar.DAY_OF_WEEK you are telling system that you are entering some value as day of the week. But instead of one specific day you are entering two. Calendar object is used to store one specific date.
Therefore, in order to get set alarms for several days, you need to set each of the alarms separately. For this reason you may create separate Calendar objects or reuse one by changing the time. However, you have same receiver class for both alarms. Therefore, you need to create different pending intents to make alarm manager differentiate them. For this reason I have shown you the example with different request_code.
calendar1.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
calendar2.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
calendar1.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
calendar1.set(Calendar.MINUTE, timePicker.getCurrentMinute());
calendar2.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
calendar2.set(Calendar.MINUTE, timePicker.getCurrentMinute());
Intent intent1 = new Intent(MyService_alarm.this, MyReceiver_Alarm.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(MyService_alarm.this, 1, intent1, 0);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(MyService_alarm.this, 2, intent1, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar1.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent1);
alarmManager.setRepeating(AlarmManager.RTC, calendar2.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent2);

AlarmManager start Alarm Instantly

I have created a form where user specify date and time and adds alarm. I take these date and time and creates Alarm using AlarmManager.
The problem is that as soon as I click on CreateRemainder button, Alarm is fired
I am using following method to pass date, time values to AlarmManager class.
int year= Integer.parseInt(splitDate[0]);
int month= Integer.parseInt(splitDate[1]);
int day= Integer.parseInt(splitDate[2]);
int hour= Integer.parseInt(splitTime[0]);
int minute= Integer.parseInt(splitTime[1]);
int second= 0;
Calendar cal = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
cal.set(Calendar.DATE,day); //1-31
cal.set(Calendar.MONTH,month-1); //first month is 0!!! January is zero!!!
cal.set(Calendar.YEAR,year);//year...
cal.set(Calendar.HOUR_OF_DAY, hour); //HOUR
cal.set(Calendar.MINUTE, minute); //MIN
cal.set(Calendar.SECOND, second);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
I debug this and its getting the correct values, but it starts alarm immediately.
If i change the AlarmManager time to hard codded 10 seconds time, it starts remainder after 10 seconds.
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10 * 1000), pendingIntent);
But if i add 10 Seconds to the Calender, it still start displaying alarm instantly after setting it.
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+10000, pendingIntent);
Usually, if the alarm is being fired as soon as you set it, it means that scheduled time is behind current time... So, AlarmManager fires it imediatelly
I suggest to add debug messages to debug. Something like:
Log.d("DEBUG", "Time from device: " + Calendar.getInstance().getTimeInMillis() + " Time passed to alarm: " + cal.getTimeInMillis());
Then, you can check Current Millis website and check if both times are correct.. Check if cal is really a future date
Also, if you want to add a time to calendar, use as follows Calendar.add() method:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Use this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC, cal.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC, cal.getTimeInMillis(), pendingIntent);
}
If your alarm is getting called instantly than my guess is your cal's date is before today.

Run Alarm In Selected Days

I want to start alarm when i have selecting the days,hours,and minutes.
This is my code so far :
public void startAt() {
Intent alarmIntent = new Intent(backgroundApplication.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(backgroundApplication.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_WEEK,calendar.WEDNESDAY);
calendar.set(Calendar.HOUR_OF_DAY,7);
calendar.set(Calendar.MINUTE,35);
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 5, pendingIntent);
}
For the example i set the DAY_OF_WEEK is today(friday) it works great. But when i changed it into Wednesday, or other day before friday it still running.
Is there any other way to start in selected days ?
According to the documentation http://developer.android.com/reference/android/app/AlarmManager.html#setRepeating%28int,%20long,%20long,%20android.app.PendingIntent%29, the 2nd parameter is the trigger time in milliseconds and if you set it to a time in the past, the alarm will trigger immediately. If you want the alarm to only start from next Wednesday, then you have to advance your Calendar time to the next Wednesday with calendar.add(Calendar.WEEK_OF_MONTH, 1). By the way, in your code, you don't need to have calendar.setTimeInMillis(System.currentTimeMillis()).Calendar.getInstance() will return the current time by default. You should also use static field Calendar.WEDNESDAY.

Alarm Manager Firing Immediately after real time has been passed

I want to set and cancel an Alarm for a particular time. I am doing the same using the TimePicker using the following code.
public void setRecurringAlarm(int randomTimer,long mills, int i){
Intent intent = new Intent(CreateAlarmActivity.this, AlarmReceiver.class);
intent.setData(Uri.parse("timer:" + i));
PendingIntent pendingIntent = PendingIntent.getBroadcast(CreateAlarmActivity.this, 1253, intent, PendingIntent.FLAG_CANCEL_CURRENT| Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,mills,
pendingIntent);
Toast.makeText(CreateAlarmActivity.this, "Alarm "+i+" isSet", Toast.LENGTH_LONG).show();
}
Note:-Suppose I set the alarm for 10:00 PM. It works fine for 10:00 PM. But when I again run the same code (after 10 PM) i.e once the time has been passed on which the alarm has been set and I recall that code (to reset the alarm), it starts running immediately. Why it is so ? I am unable to get where I am a wrong.
You can check if the alarm time is before the current time or not. If so, then set the alert time for the next day (if you want to fire alarm at least once, or want to set Repeating alarm).
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, 0);
if (System.currentTimeMillis() > cal.getTimeInMillis()) {
calendar.add(Calendar.DATE, 1);
}
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
public void scheduleAlarm() {
// time at which alarm will be scheduled here alarm is scheduled at 1
// day from current time,
// we fetch the current time in milliseconds and added 1 day time
// i.e. 24*60*60*1000= 86,400,000 milliseconds in a day
// Long time = new GregorianCalendar().getTimeInMillis()+24*60*60*1000;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, 20);
cal.add(Calendar.MINUTE, 00);
cal.add(Calendar.SECOND, 00);
Intent intent = new Intent(CreateAlarmActivity.this, AlarmReceiver.class);
// create the object
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
PendingIntent.getBroadcast(this, 1, intentAlarm,
PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(this, "Alarm Scheduled ", Toast.LENGTH_LONG)
.show();
}
Hope this will help you
2 things:
If you are "recalling that code" by calling setRecurringAlarm(randomTimer, mills, i) using the same value for the mills parameter, then the time for the alarm will be in the past and it will trigger immediately (if you schedule an alarm with a trigger time in the past, the alarm triggers immediately).
Please remove | Intent.FILL_IN_DATA from the call to PendingIntent.getBroadcast(). It doesn't belong there as this parameter should contain only PendingIntent flags and it may do some damage.

How do I register the AlarmManager to repeat selected days?

I'm creating an alarm application.
In my application, the user can select the days to fire the alarm, such as Sunday, Monday, so I used the Calendar class and AlarmManager to register multiple alarms.
If the selected day or days are less than the current day of the week, the alarm fires immediately.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, getDayint); //sunday = 1
calendar.set(calendar.HOUR_OF_DAY, gethour);
calendar.set(calendar.MINUTE, getmin);
calendar.set(calendar.SECOND, 0);
calendar.set(calendar.MILLISECOND, 0);
long TIM = calendar.getTimeInMillis();
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, TIM, sender);
//repeat weekly
am.setRepeating(am.RTC,TIM, AlarmManager.INTERVAL_DAY*7, sender);
By using PendingIntent.FLAG_UPDATE_CURRENT you say that you like to have only one such alarm - so latest one wins - only one alarm weekly. And if TIM lies in past, alarm is fired immediately ( and then repeating ) So far - everything works as designed.
You may check whether TIM ( by the way, it is variable, and concention is that they shall be not uppercased like constants ) is less than System.currentTimeMillis() and add one week to it in this case

Categories

Resources