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.
Related
The reference for Alarm Manager says that
If the stated trigger time is in the past, the alarm will be triggered
immediately.
I am facing this problem in my application. Here is my alarm manager code :
Intent myIntent = new Intent(getActivity(), DinnerAlarmReceiver.class);
pendingDinnerIntent = PendingIntent.getBroadcast(getActivity(), 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingDinnerIntent);
Is there any workaround to this problem?
-----EDIT------
I have written some code to estimate if the set time for the alarm is before the current time . Here is the above portion with corresponding changes :
Calendar calendar = Calendar.getInstance();
long currentTime = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
long setTime = calendar.getTimeInMillis();
Timestamp setTimestamp = new Timestamp(setTime);
Timestamp currentTimestamp = new Timestamp(currentTime);
if (setTimestamp.after(currentTimestamp))
{
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingDinnerIntent);
}
else
{
}
What should I the alarmManager to in case setTimestamp is before currentTimestamp ?
You don't need to create Timestamps. You can do it with your Calendar.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
if(calendar.before(Calendar.getInstance())) {
calendar.add(Calendar.DATE, 1);
}
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingDinnerIntent);
I would also mention that as of KitKat, if your targetSdkVersion is 19 or above, the AlarmManager#set() method is not exact. If you want your alarm to fire at an exact time, you'll need to use a setExact*() method.
The reference for Alarm Manager says that
If the stated trigger time is in the past, the alarm will be triggered
immediately.
I am facing this problem in my application. Here is my alarm manager code :
Intent myIntent = new Intent(getActivity(), DinnerAlarmReceiver.class);
pendingDinnerIntent = PendingIntent.getBroadcast(getActivity(), 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingDinnerIntent);
Is there any workaround to this problem?
-----EDIT------
I have written some code to estimate if the set time for the alarm is before the current time . Here is the above portion with corresponding changes :
Calendar calendar = Calendar.getInstance();
long currentTime = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
long setTime = calendar.getTimeInMillis();
Timestamp setTimestamp = new Timestamp(setTime);
Timestamp currentTimestamp = new Timestamp(currentTime);
if (setTimestamp.after(currentTimestamp))
{
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingDinnerIntent);
}
else
{
}
What should I the alarmManager to in case setTimestamp is before currentTimestamp ?
You don't need to create Timestamps. You can do it with your Calendar.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
if(calendar.before(Calendar.getInstance())) {
calendar.add(Calendar.DATE, 1);
}
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingDinnerIntent);
I would also mention that as of KitKat, if your targetSdkVersion is 19 or above, the AlarmManager#set() method is not exact. If you want your alarm to fire at an exact time, you'll need to use a setExact*() method.
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);
I am trying to use a calendar to set an alarm manager to go off every Sunday. When I open the app, the alarm starts immediately and repeats everyday instead of once every Sunday.
CODE:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, 1);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000, pi);
I think you have a math issue. Change to:
24*60*60*1000*7
Since before, you were repeating every 24h
24*60*60*1000 = 86400000 millis = 24h
24*60*60*1000*7 = 24h * 7 = 1 week
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);