I have seen a lot of tutorials for creating an AlarmManager and bringing up a notification at a specific date, but I was wondering how to do it for X days before.
For example, if I have an event on January 8th, 2014 and I want to set it a week before to Jan 1st, 2014, I would just set the alarm as this:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.YEAR, 2013);
calendar.set(Calendar.DAY_OF_MONTH, Day-7);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM,Calendar.AM);
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
However what if the event was on January 4th, 2014, then I would want to set the date to December 28th, 2013. Is there a function that can do this? Or do I have to write a lot of cases?
the event was on January 4th, 2014:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.YEAR, 2014);
calendar.set(Calendar.DAY_OF_MONTH, 4);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
long eventTime=calendar.getTimeInMillis();//Returns Time in milliseconds
long oneDay=AlarmManager.INTERVAL_DAY;//Converts 24 Hrs(1 Day) to milliseconds
int noOfDays=4
long reminderTime=eventTime-(noOfDays*oneDay);//Time in milliseconds when the alarm will shoot up & you do not need to concider month/year with this approach as time is already in milliseconds.
//Set alarm
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, reminderTime, pendingIntent);
Hope this helps!
get your current time in milliseconds and subtract the no. of days from it,here 1 day= 24*60*60*1000 = 86400000
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, (calendar.getTimeInMillis()-(no. of days * 86400000)), pendingIntent);
Related
In my application I have a functionality to trigger alarm in 4 senerios:
Only once for a user chosen date and time
Daily for chosen time
Weekly according to chosen date and time
User chosen custom days of the week
I successfully implement the first 3 senerios by using the follow:
Only once:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(date[0]));
calendar.set(Calendar.MONTH, (Integer.parseInt(date[1])) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(date[2]));
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
For daily scheduling:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
calendar.set(Calendar.SECOND, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
For weekly scheduling (as per system date):
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
calendar.set(Calendar.SECOND, 0);
//long interval = calendar.getTimeInMillis() + 604800000L;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, pendingIntent);
For custom weekdays chosen by user (ex. only for monday and friday, repeated weekly) I am using the same code that I used for weekly scheduling by iteration. But its not working for monday (which is set before friday) and working for friday. Also, it does not trigger the alarm for today if today (system date) is a monday or a friday.
So how do i implement weekly alarm scheduling for custom days of the week?
There isn't a way for you to tell Alarm manager which days you want to it trigger.
One solution would be to have an alarm for each day of the week you want it to trigger repeating weekly.
So for your Monday and Friday scenario, you would set a weekly repeating reminder on Monday and a weekly repeating reminder on Friday.
Example code:
private void scheduleAlarm(int dayOfWeek) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
// Check we aren't setting it in the past which would trigger it to fire instantly
if(calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DAY_OF_YEAR, 7);
}
// Set this to whatever you were planning to do at the given time
PendingIntent yourIntent;
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, yourIntent);
}
private void setUpAlarms() {
scheduleAlarm(Calendar.MONDAY);
scheduleAlarm(Calendar.FRIDAY);
}
1) sunday=1, moday=2;, tuesday=3,......saturday=7
2)selectedDays.size()*(it will be which date you have selected , if you seleted monday , tues ,friday , then it will 3 size )*
3) for time if we choose from datetimepicker
**String[] timespilt = tv_timepicker.getText().toString().split(":");**
for (int i = 0; i < selectedDays.size(); i++) {
// for alarm ...
calNow = Calendar.getInstance();
calSet = (Calendar) calNow.clone();
int day = calSet.get(Calendar.DAY_OF_WEEK);
calSet.set(Calendar.HOUR_OF_DAY,Integer.parseInt(timespilt[0].trim()));
calSet.set(Calendar.MINUTE, Integer.parseInt(timespilt[1].trim()));
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
calSet.set(Calendar.DAY_OF_WEEK,selectedDays.get(i));
if (calSet.compareTo(calNow) <= 0) {
//Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE,7);
}
System.out.println("set time for alarmweekly==="+calSet.getTime());
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmPI = PendingIntent.getBroadcast(this, (int) insertedId+selectedDays.get(i), alarmIntent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), alarmPI);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calSet.getTimeInMillis(), (DateUtils.DAY_IN_MILLIS) * 7,
alarmPI);
}
You have said that you used the same code of your weekly scheduling, "by iteration". If I understand you are trying to set multiple alarm (two in your example) with the same PendingIntent.
The problem is that as the documentation says
When you set a second alarm that uses the same pending intent, it
replaces the original alarm.
This is way only the second alarm is triggered.
So in order to solve your problem you simply need to use a different PendingIntent for each scheduling.
I need to add push notifications in my Android application. The notification must be shown every day at certain time (for example at 1 PM). To do this i am using an AlarmManager. I am registering an alarm, when the app is starting for the first time. But i got a problem.
If i am installing my application onto device, for example at 1.10 PM, then the alarm is running right after my app is started. But this is wrong, because I need this alarm to run in the next day, not in the current day. Can anyone help me and tell how to set daily alarm, that must start working on the day about from current day.
This is my code, which i am using for now
private void registerAMAlarmManger(){
mAMAlarmIntent = new Intent(this, AMAlarmReceiver.class);
mAMPendingIntent = PendingIntent.getBroadcast(this, 0, mAMAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
SharedPreferences sPrefs = getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE);
int amTime = sPrefs.getInt(Constants.MORNING_TIME, 9);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, amTime);
calendar.set(Calendar.MINUTE, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, mAMPendingIntent);
}
if the time has passed for the current date it executes the code of performing alarm .This need to be handled . I do it by following way
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, mytesthourofday);
calendar.set(Calendar.MINUTE,
Integer.parseInt(min_am_pm[0]));
// calendar.set(Calendar.AM_PM, am_pm_integer);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 1000 * 24 * 60 * 60,
pendingIntent);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, mytesthourofday);
calendar.set(Calendar.MINUTE,
Integer.parseInt(min_am_pm[0]));
// calendar.set(Calendar.AM_PM, am_pm_integer);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 1000 * 24 * 60 * 60,
pendingIntent);
Why does the alarm set off immediately instead of the specified time?
Intent myIntent = new Intent(Notepad.this, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getService(Notepad.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.YEAR, 2012);
calendar.set(Calendar.MONTH, 4);
calendar.set(Calendar.DAY_OF_MONTH, 5);
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 4);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
If I use only calendar.add(Calendar.SECOND, 5);, it sets off after 5 seconds.
SOLUTION based on Nicholas' answer
Date dat = new Date();//initializes to now
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_now.setTime(dat);
cal_alarm.setTime(dat);
cal_alarm.set(Calendar.HOUR_OF_DAY,Integer.valueOf(h));
cal_alarm.set(Calendar.MINUTE, Integer.valueOf(m));
cal_alarm.set(Calendar.SECOND,0);
if(cal_alarm.before(cal_now)){
cal_alarm.add(Calendar.DATE,1);
}
To me it seems that you are setting the calendar time and day to the alarm time. Maybe set up two different calendars and have one for the current time and another for the alarm time. Does that make sense?
Its about a small android application that will take hours as input from user for every day of week and turn on / off blue tooth device accordingly for the respective day regardless of the "Date". i.e the code should only check the day, hour and minute. i have used following code (for testing purpose for today i.e Friday) but it do not triggers the alarm.
//..........setting calender for MyAlarmService
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 5);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
// here it m setting the "Today"
cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
Intent myIntent = new Intent(AndroidAlarmService.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(AndroidAlarmService.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
when i remove the statement
cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
The AlarmService triggers perfectly "Today" on the time specifed above i.e 11:05 AM
What am i doing wrong?
found a work around as follows.
//..........setting calender for Friday
Calendar calFri = new GregorianCalendar();
calFri.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
calFri.set(Calendar.HOUR_OF_DAY, friHrInt);
calFri.set(Calendar.MINUTE,friMinInt);
calFri.set(Calendar.SECOND, 0);
calFri.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
calFri.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
calFri.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
days = 13 - calFri.get(Calendar.DAY_OF_WEEK); // how many days until Sunday
calFri.add(Calendar.DATE, days);
//..........setting calender for Saturday
Calendar calSat = new GregorianCalendar();
calSat.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
calSat.set(Calendar.HOUR_OF_DAY, satHrInt);
calSat.set(Calendar.MINUTE,satMinInt);
calSat.set(Calendar.SECOND, 0);
calSat.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
calSat.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
calSat.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
days = 14 - calSat.get(Calendar.DAY_OF_WEEK); // how many days until Sunday
calSat.add(Calendar.DATE, days);
and then i use separater alarm service for these days as follows
//.........................The Following will make the alarm go off on friday......................................
Intent myIntentFri = new Intent(AndroidAlarmService.this, FriOffAlarmService.class);
pendingIntentFri = PendingIntent.getService(AndroidAlarmService.this, 0, myIntentFri, 0);
AlarmManager alarmManagerFri = (AlarmManager)getSystemService(ALARM_SERVICE);
//alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent2);
alarmManagerFri.setRepeating(AlarmManager.RTC_WAKEUP, calFri.getTimeInMillis(),interval, pendingIntentSun);
//.........................The Following will make the alarm go off on saturday......................................
Intent myIntentSat = new Intent(AndroidAlarmService.this, SatOffAlarmService.class);
pendingIntentSat = PendingIntent.getService(AndroidAlarmService.this, 0, myIntentSat, 0);
AlarmManager alarmManagerSat = (AlarmManager)getSystemService(ALARM_SERVICE);
//alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent2);
alarmManagerSat.setRepeating(AlarmManager.RTC_WAKEUP, calSat.getTimeInMillis(),interval, pendingIntentSat);
I am trying to set an alarm every 5th day of the week and the 24th hour of that day.
Here is the code i am using. Ive been reading over the Calendar and AlarmManager docs, a
and here is what i have came up with.
String alarm = Context.ALARM_SERVICE;
//Alert for game covers
am = (AlarmManager)context.getSystemService(alarm);
calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, 5);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Intent Aintent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, Aintent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, pi);
Is this correct for what i want to do?
To get a Calendar instance, that points to a date 5 days in the future, you take the current date and add 5 days like this:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 5);
Then you set your alarm:
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
pendingIntent);