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.
Related
I'm currently trying to make an alarm app that will mute all audio volume at the user-defined day and time. However, the alarm seems not fired at the correct time. I found that the alarm is always fired earlier.
This is my set alarm code:
public static void setAlarm(Context context, String time, int day, int reqCode) {
String[] timeSplit = time.split(":");
Calendar calendar = Calendar.getInstance();
int hour = Integer.parseInt(timeSplit[0]);
int minute = Integer.parseInt(timeSplit[1]);
int days = (day-calendar.get(Calendar.DAY_OF_WEEK) + calendar.get(Calendar.DAY_OF_MONTH));
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
days,
hour,
minute,
0
);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, RuleAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, reqCode, intent, 0);
// Set the alarm to be fired every week on the selected day
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 7 * 24 * 60 * 60 * 1000, pendingIntent);
Toast.makeText(context, "Alarm is set", Toast.LENGTH_SHORT).show();
}
I have tried to change setRepeating() to setInexactRepeating() but nothing changed.
AlarmManger is inexact to save battery by combining wakeup calls.
https://developer.android.com/reference/android/app/AlarmManager.html
Try this
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 7 * 24 * 60 * 60 * 1000, pendingIntent);
The problem is that if you are creating PendingIntent for an alarm for past time it will be fired immediately.If you would like to prevent that happening, then simply do not set alarms with a past trigger time . Use BroadcastReceiver for receiving alarm.
Update :
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);
}
I finally find out the problem. It lies on the day params. What I pass to day params is my Spinner selected position which starts from zero while the Calendar days starts from one (SUNDAY = 1, MONDAY = 2, so on). So, the alarm will always be set in the past days. I plus one to the day params and it's worked.
This is my piece of code where the startAlarm() function got called.
String ruleStartTime = rule_startTime.getText().toString();
// Spinner index starts from zero,
// to match with the Calendar day indexing, we need to plus it one
int dayIdx = day.getSelectedItemPosition()+1;
Alarm.setAlarm(getApplicationContext(), ruleStartTime,
dayIdx, 0);
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 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 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.
I have following piece of code which should be trigger alarm after 2 days. However It gets triggered after every 2 hours, some users says they get it after every 5 mins too.
settingDB.updateSetting("Notification",1);
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.set(Calendar.HOUR_OF_DAY, 10);
Calendar_Object.set(Calendar.MINUTE,01);
Calendar_Object.set(Calendar.SECOND, 0);
//Calendar_Object.set(Calendar.DAY_OF_WEEK, 1);
// MyView is my current Activity, and AlarmReceiver is the
// BoradCastReceiver
Intent myIntent = new Intent(Setting.this, TimeAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Setting.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
//Log.w("alarm set for " , Calendar_Object.getTime().toString ());
/*
* The following sets the Alarm in the specific time by getting the long
* value of the alarm date time which is in calendar object by calling
* the getTimeInMillis(). Since Alarm supports only long value , we're
* using this method.
* 3*1000*24*3600
*/
//alarmManager.setRepeating(AlarmManager.RTC, Calendar_Object.getTimeInMillis(),3600*1000**24,pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC, Calendar_Object.getTimeInMillis(), 86400000*2, pendingIntent);
Could you please help me to resolve the problem?
The calendar object passed to alarm manager is set to a fixed time. This will cause the alarm to go off when that time comes.
you could also do this
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
+ 60*1000,timeofAlarm pendingIntent);
The calendar object you passed seems to do the damage. Follow my example above , once the alarm will go off after like a min. Just to check if the alarm is working,(you may want to add anytime there ,its upto you).
Realtime is useful(and perhaps recommended) if you want your alarm to go off every given time, irrespective of user time state