I am trying to trigger action everyday at 00:00:00 AM using AlarmManager but the problem is first time action is triggered quickly and then works as expected. First time, action triggers as soon as the code is run. Please see the following code:
private void setAlarmManagerForDateChange()
{
Intent intent = new Intent(this, DateTimeChangeReceiver.class);
intent.putParcelableArrayListExtra("names", names);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
999, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
24 * 60 * 60 * 1000, pendingIntent);
}
It action triggers before 00:00:00 AM for the first time. Please point out what is being missed. Thanks,
You're scheduling the alarm in the past, which causes the AlarmManager to fire instantly.
You take the current date (e.g. 05/29/14 20:08:32), and set the hour, minute and second to 0.
What you get is: 05/29/14 00:00:00.
What you actually want, is to add another day to get to 06/29/14 00:00:00.
calendar.add(Calendar.DAY, 1);
Related
Below is the code I am using to create alarms when data is pulled from external API. If the time set is in the past, the alarm goes off as soon as it is set(2 second gap). For example if I set the alarm for 8:00 AM, 10th April at 10:00 AM on 11th April(Past time). It starts the alarm as soon as it is set.
public static final int ALARM_REQUEST_CODE = 1001;
public static AlarmManager alarmManager = (AlarmManager) EHCApplication.getInstance().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
public static Intent alarmIntent = new Intent(EHCApplication.getInstance().getApplicationContext(), AlarmReceiver.class);
public static PendingIntent pendingIntent = PendingIntent.getBroadcast(EHCApplication.getInstance().getApplicationContext(), ALARM_REQUEST_CODE, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
public static void setAlarm(Reminder rm) {
for (ScheduledTime time : rm.getScheduledTime()) {
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.ARGS_SELECTED_MEDICINE, medicine);
alarmIntent.putExtras(bundle);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMilliseconds(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
I am expecting the alarm to go off from next time it hit the time. Where am I making mistake?
This is the expected behavior.
From the documentation of setRepeating() (and other AlarmManager set methods):
If the stated trigger time is in the past, the alarm will be triggered
immediately
If you would like to prevent that happening, then simply do not set alarms with a past trigger time (e.g. check against System.currentTimeMillis() when setting the alarm).
Well, I ran into same problem and after studying I found that alarm will be run as soon when past time is set for the alarm.
Source: Here is documentation of Alarm Manager - setRepeating()
So, I resolved the issue by checking if "Calendar time is in past from system time than I add a day"
Working code:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, min);
calendar.set(Calendar.SECOND, 0);
alarmManager.cancel(pendingIntent);
// Check if the Calendar time is in the past
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
Log.e("setAlarm","time is in past");
calendar.add(Calendar.DAY_OF_YEAR, 1); // it will tell to run to next day
}
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); //Repeat every 24 hours
If I call the setinexactrepeating() alarm method in the onCreate , how does it affect the alarm which is being repeated at the specified interval
Here is the code of setting alarm, I am calling this method in the onCreate()
public void setAlarm()
{
Intent myintent=new Intent(this,AlarmReciever.class);
Random random = new Random();
int ran = random.nextInt(total_words.size());
String tempString=onlySearch(total_words.get(ran), 1);
myintent.putExtra("word", total_words.get(ran));
myintent.putExtra("meaning", tempString);
myintent.putExtra("language", 1);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,101,myintent,PendingIntent.FLAG_UPDATE_CURRENT);
//NotificationTime is the sharedPreference file, in which i am storing hours and minute got from timepicker
alarmManager.cancel(pendingIntent);
Calendar calendar=Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, NotificationTime.getInt("hour", 12));
calendar.set(Calendar.MINUTE, NotificationTime.getInt("min", 0));
calendar.set(Calendar.SECOND, 0);
if(calendar.before(Calendar.getInstance()))
calendar.add(Calendar.DATE,1);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY
, pendingIntent);
System.out.println("ALARM SET STATUS");
}
Alarm is first scheduling at the exact time perfectly but it does not gets repeated.
Actually I wanted to show notification daily at the specified time and I am passing a String with the intent. By default I had set to 12:00 PM but user can change its time. The first notification after setting time (or the first alarm) is working but its repetition is not working.
Please have a look, and if someone knows a better solution to show notification daily at the same specified time it would be appreciated if you tell me.
Thanks in advance
user setRepeating for Repeating Alarm
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
/* Repeating on every interval */
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
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.
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.
I set an AlarmManager to open notification every 24 hours.
But every time I open the activity, the notification starts.
So how to set it not to show the notification when the activity is already opened?
This is my AlarmManager code:
AlarmManager alarmManager = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
Intent intent = new Intent(this, myService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
long when = calendar.getTimeInMillis(); // notification time
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC, when, 24*60*60*1000, pendingIntent); //every 24 hours
Thanks ,
Your when variable points to the current time, hence the alarm will be fired right at execution of that part. Change when to calendar.getTimeInMillis(). Your calendar variable is set to the hour 20 of the day and repeating the day after. Here is a working copy