I have set the start time and end time of my alarm as below:
Calendar startalarmTime = Calendar.getInstance();
startalarmTime.setTimeInMillis(System.currentTimeMillis());
startalarmTime.set(Calendar.HOUR_OF_DAY, 11);
startalarmTime.set(Calendar.MINUTE, 30);
startalarmTime.set(Calendar.SECOND, 0);
Calendar endalarmTime = Calendar.getInstance();<br>
endalarmTime.setTimeInMillis(System.currentTimeMillis());
endalarmTime.set(Calendar.HOUR_OF_DAY, 11);
endalarmTime.set(Calendar.MINUTE, 31);
endalarmTime.set(Calendar.SECOND, 0);
int repeatingInterval = 5; //5 seconds
long endTime = endalarmTime.getTimeInMillis();
long startTime = startalarmTime.getTimeInMillis();
I'm setting the repeating alarm as below:
Intent broadCast = new Intent(ctx,AlarmBroadCaster.class);
broadCast.putExtra("endTime", endTime);
pIntent = PendingIntent.getBroadcast(ctx, 12345, broadCast, Intent.FILL_IN_DATA);
AlarmManager alrmMgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
alrmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,startTime,repeatInterval*1000, pIntent);
The alarm rings well at 11:30 and repeats for every 5 seconds which is fine.
To cancel the alarm at 11:31 I have written the following piece of code in onReceive() of my BroadCastReceiver as below:
public void onReceive(){
if(System.currentTimeMillis()==alarmEndTime){
AlarmManager alarmManager = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
alarmManager.cancel(pIntent);
Toast.makeText(context,"Cancelled Endtime",Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml :
<receiver android:name="com.andr.broadcastreceiverdemo.AlarmBroadCaster"></receiver>
The Alarm never cancels when it reaches end time .
Can any one help me how to cancel the alarm when it reaches some time .
Change it to
if(System.currentTimeMillis()>alarmEndTime) to stop as soon as the system time exceeds the alarm end time. == checks if its exactly equals and misses most of the time.
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
I am setting alarm usng this
Calendar now = Calendar.getInstance();
Calendar alarm = Calendar.getInstance();
alarm.set(Calendar.HOUR_OF_DAY,21);
alarm.set(Calendar.MINUTE,30);
if (alarm.before(now)) {
alarm.add(Calendar.DAY_OF_MONTH, 1); //Add 1 day if time selected before now
}
AlarmManager alarmManager =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context,Receiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context,(int)alarm.getTimeInMillis(),i,0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, (int)alarm.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pi);
But even if I schedule it for next day,it triggers immediately after saving alarm.
Dont know what the issue is have searched a lot but everyone else gets it working
You are casting a long timestamp to int thus losing bits and changing the actual timestamp value. You end up with a time that already has passed so it executes the intent immediately.
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Notice that I removed the (int) cast in the last line.
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 have a scheduleAlarm class which is supposed to set the alarm in a specific time, however the alarm is being fired immediately after the method is called. I've checked that provided time in milliseconds is fine, so I've no idea what's going on.
private void scheduleAlarm(int day, int startHour, int startMinute, String info) {
AlarmManager mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, day);
c.set(Calendar.HOUR, startHour);
c.set(Calendar.MINUTE, startMinute);
Intent startIntent = new Intent(this, Recorder.class);
startIntent.putExtra("info", "someinfo");
Log.v("millis", String.valueOf(c.getTimeInMillis())); // time is okay
Random mRandom = new Random();
int randomInt = mRandom.nextInt();
PendingIntent pendingIntent = PendingIntent.getService(this, randomInt, startIntent,PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
Just make sure that the time set for the alarm is after current time.
There is an easy way to check that.
just do
Calendar.getInstance().getTimeInMilis() - c.getTimeInMillis()
Log this result, and you can see if the second is before the first.
Lets say now is 4 o'clock, and you set the same day and 3 o'clock. it will get activated instantly.
Other than that i see no reason why it should fail.
Another way to test would be to use currentTime and add lets say 10k miliseconds and see if it activates in 10 seconds after you test it. Then you are sure that the time set is wrong in your case.
Ok, let me modify the question and make it much easier. I Hope you'll be able to get me the solution for this. Both the alarms should be scheduled simultaneously, which is not happening here. I am even using unique requestcode for the pending intent. HELP ME please.....
//On click Listener
private OnClickListener mOneShotListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, 0);
//I even tried sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, PendinIntent.FLAG_UPDATE_CURRENT);
//the alarm to go off 30 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
//adds 2 minutes to the time
calendar.add(Calendar.MINUTE, 2);
sender = PendingIntent.getBroadcast(AlarmController.this,1, intent,0);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender2);
}
};
OLD Question:
I want to set two alarms at the same time for two different operations to be performed.
For Eg. A user sets alarm at 2'O clock and sets the duration to 15 mins. The first alarm should fire at 2'O clock which performs function1 and the second alarm should fire at 2:15 as the user specified the duration as 15 mins which performs the function2. This operation should be repeated everyday at 2'O clock unless the user changes the time.
I am calling this both functions on button click:
On Click Event
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
..........
..........
new ReminderManager(this).setReminder(mRowId, mCalendar);
new ReminderManager(this).wakeReminder(mRowId, mCalendar, duration);
}
}
The setReminder contains
//sets alarm at 2'O clock
public void setReminder(Long taskId, Calendar when, String duration){
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext,(int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}
The wakeReminder contains
//adds duration i.e. 15mins
public void wakeReminder(Long taskId, Calendar when, String duration){
Intent i = new Intent(mContext, OnAlarmReceiverWake.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
Long d = Long.parseLong(duration);
Long mins = d*60*100;
Long milli = when.getTimeInMillis() + mins;
PendingIntent pi = PendingIntent.getBroadcast(mContext, (int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, milli, pi);
}
I have noticed that whenever mAlarmManager.set(); is executed successfully the LogCat shows notification like
"enqueueToast pkg=com.jellboi.android.togglemode callback=android.app ITransientNotification$stub$proxy#43c0c5f8 duration=0"
but when I set both the alarms simultaneously the notification is not shown when the mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); is executed
but the notification is shown when mAlarmManager.set(AlarmManager.RTC_WAKEUP, milli, pi); is executed. Also the notification is set for the original time i.e. 2'O clock and not after adding 15mins to it's duration.
Please help, I tried a lot of ways to call this functions at different places like after the 1st alarm is fired but all in vain.
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, 0);
You have problem in this line. If you want to simultaneously fire two alarma then you should do something like this
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,giveUniqueRequestIdsHere, intent, 0);
sender = PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), i, PendingIntent.FLAG_ONE_SHOT);
Do the same for your PendingIntent.getActivity();
Hi try using this to generate request I was generating my own request code but this line worked for me
final int intent_id = (int) System.currentTimeMillis();
When launch new OneShotAlarm.class, it have to design launch mode. Default setting would ignore the second time launch, if the first instance still existed.
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
seems like you forgot to set "sender2" before your second call.
you change the value of sender, then put sender2 as the argument.
You can create an array of your task in the Service class and set the array in the for loop, inside the for loop you can call your task simultaneously at the same time.
Try this:
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
cal.clear();
Cursor c = database.query(mArray.get(mPosition), new String[]{"days"},"days"+"!="+0, null, null, null, null);
cal.set(Calendar.YEAR,2011);
cal.set(Calendar.MONTH,date.getMonth());
cal.set(Calendar.DAY_OF_MONTH,date.getDate());
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(nextScreen.this, AlaramReciver.class);
i.putExtra("Start",mArray.get(mPosition));
Editor medit = getSharedPreferences("Start", 0).edit();
medit.putString("Start", mArray.get(mPosition));medit.commit();
PendingIntent pendingintent = PendingIntent.getBroadcast(this,mPosition, i, 0);
mgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingintent);
You have set to the time like this, and once you set time in alarm manager it will automatically call the functions daily. Use different request code for pendingintent.
If you want call second function. You just add the time in 15 min in the
cal.set(Calender.MINUTE,min+15);