I am trying to implement a daily alarm.
Intent intent = new Intent(mActivity, AlarmReceiver.class);
intent.putExtra("weekdays", weekdays);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mActivity.getApplicationContext(), weekdays ? WEEKDAYS_ID : WEEKENDS_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar current = Calendar.getInstance();
time.set(Calendar.SECOND, 0); // time a type of Calendar object which is set from TimePicker
long timeDifference = time.getTimeInMillis() - current.getTimeInMillis();
long triggerAt = (timeDifference > 0 ? time.getTimeInMillis() : AlarmManager.INTERVAL_DAY + timeDifference);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAt, AlarmManager.INTERVAL_DAY, pendingIntent);
It works fine if I set a time in future.
But if the time difference is negative (current time- 8:00, picked time- 7:45), the repeating alarm is set instantly and the broadcast receiver is fired!
Though I have added AlarmManager.INTERVAL_DAY with the timeDifference to set it after a day, it isn't working.
Also, The AlarmManager.INTERVAL_DAY value is (86400000) which is smaller than the current time in milis (1387869223432), so adding it doesn't make much difference!
What am I missing here?
Ok, this is not working.
long triggerAt = (timeDifference > 0 ? time.getTimeInMillis() : time.getTimeInMillis() + AlarmManager.INTERVAL_DAY + timeDifference);
After debugging, I found that if I set earlier time, then add one day time - difference then the trigger time gets lower than the current time!
Alarm time: 1388073636969 (8am) current time: 1388130756977 (11:50pm)
Difference: -57120008
Alarm to be Triggered: 1388102916961
// its alarm time (8am) + one day interval (1 day) -difference (4hr)
How come trigger time gets smaller than current time??
You should add currentTimeInMillis too
current.getTimeInMillis() + AlarmManager.INTERVAL_DAY + timeDifference
If timeDifference is -15 minutes, the above statement will add-up to,
current time + 24 hours - 15 minutes, which is what you want I presume.
AlarmManager.INTERVAL_DAY : Available inexact recurrence interval recognized by setInexactRepeating(int, long, long, PendingIntent) when running on Android prior to API 19.
Related
In my app, I am letting the user select some days out of the week and they will also set a time. Something similar to alarm clock, except in this case, I will be starting a service on the specified day and time.
With the below code, my broadcast receiver is getting called, but it's getting called even on the days not selected by the user.
val startCalendar = Calendar.getInstance()
for (dayNum in selectedDays.values) {
var intent = Intent(activity, DeviceLocationSharingStarter::class.java)
intent.putExtra("startTime", true)
val pendingIntent = PendingIntent.getBroadcast(activity, dayNum, intent, PendingIntent.FLAG_UPDATE_CURRENT)
startCalendar.set(Calendar.HOUR_OF_DAY, 15)
startCalendar.set(Calendar.MINUTE, 40)
startCalendar.set(Calendar.DAY_OF_WEEK, dayNum)
if(startCalendar.timeInMillis < System.currentTimeMillis()) {
startCalendar.add(Calendar.DAY_OF_YEAR, GregorianCalendar().get(Calendar.DAY_OF_WEEK)-1)
}
var alarmManager = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startCalendar.timeInMillis, AlarmManager.INTERVAL_DAY * 7, pendingIntent)
}
My selected days is a Collection and it has values like ("Monday" to 2, "Friday" to 6), but it's Tuesday today and while testing my broadcast receiver was called at the time specified.
How do I fix this to only get fired during the days specified in selectedDays collection?
Edit - I even tried setting intervalMillis in setRepeating function to "7 * 24 * 60 * 60 * 1000" and also to "24 * 60 * 60 * 1000", still the broadcast receiver gets called on the days not set.
I have a service, which should start every hour. I am testing with a Note 3.
As this is Android KitKat I changed the code to:
AlarmManager am = (AlarmManager) this.getSystemService(ALARM_SERVICE);
int valueOfHour = 3600000;
long time = System.currentTimeMillis()+ (valueOfHour - (System.currentTimeMillis() % valueOfHour))+ 300000;
Log.i("Calculated Time:", time + " " + System.currentTimeMillis());
if(android.os.Build.VERSION.SDK_INT >=android.os.Build.VERSION_CODES.KITKAT){
am.cancel(pintent);
am.setExact(AlarmManager.RTC_WAKEUP, time, pintent);
}
My problem is, that the Service is started at XX:05 (like I want it to) and also now and then at XX:34. I just don't know why. The calculated time is always right.
The code above is located in the onBind() Method.
Hi guys this is what i have so far:
PendingIntent sender = PendingIntent.getBroadcast(mainactivity, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
showmsg();
the alarm comes after 10 seconds How can I make it in desire time i want, I have set a timepicker so how can i do it depending on the timepickers time to ring the alarm?
Thanx.
With your TimePicker, call picker.getCurrentHour() and picker.getCurrentMinute(). Use these values to calculate the total milliseconds of the given time of day (12:00 pm would equal 43200000 ms, for example) by multiplying by the milliseconds in an hour (3600000) or minute (60000). Then get the milliseconds of today's date when it started at 0:00. That would all look like this:
//time of day in ms
long totalTimePickerMs = (picker.getCurrentHour() * 3600000) + (picker.getCurrentMinute() * 60000);
//today's date in ms
Calendar c = Calendar.getInstance();
Date d = c.getTime();
long today = d.getDay() + d.getMonth() + d.getYear();
long total = today + totalTimePickerMs;
Essentially you are getting today at midnight (0:00) in milliseconds and adding to it the milliseconds of the specific time of day.
Then like you did before, except set the alarm with total as the second parameter.
I am using this code to create an Alarm in a activity that can be launched by the user.
The Alarm sends an intent that launches a broadcast reciever and then a service.
private void setGameAlerts(){
//Setting alarm to fire off NEW_GAME intent every 24 hours.
String alarm = Context.ALARM_SERVICE;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
AlarmManager am = (AlarmManager)getActivity().getSystemService(alarm);
Intent intent = new Intent("NEW_ITEM");
PendingIntent sender = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, sender);
Log.e("RELEASE LIST", "ALARM Set For 1 day from " + calendar.getTimeInMillis());
For some reason EVERYTIME the activity is launched it Automatically sends this intent and the service is launched. is there something wrong with my code that is causing this to happen other than the alarm going off everyday at 8 oclock?
It looks to me like you're setting it for 8am TODAY, not 8am tomorrow. For example, if I run this code:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
Log.i("Test", "Current time: " + System.currentTimeMillis() );
Log.i("Test", "Calendar time: " + calendar.getTimeInMillis() );
calendar.add(Calendar.DATE, 1);
Log.i("Test", "Calendar time with a day added: " + calendar.getTimeInMillis() );
I get the result:
10-06 23:26:50.050: INFO/Test(8890): Current time: 1317968810056
10-06 23:26:50.050: INFO/Test(8890): Calendar time: 1317913200000
10-06 23:26:50.050: INFO/Test(8890): Calendar time with a day added: 1317999600000
The calendar time is a number less than the current time, so therefore that calendar entry is in the past. It might make some sense that Android would immediately send the intent for an event that has past. If you add a day to it, or specify a date in your Calendar object, it should work.
Note that this numerical dates are simply the standard Unix time with milliseconds added on. If you drop the last three digits and put the number into a Unix time converter, you'll be able to check that the numbers you're working with make sense. Eg: use 1317999600 with the Unix time converter and you'll get 10am EST, which is 8am PST (my time zone).
I hope that helps!
In Android we set an alarm by setting the time until it goes off in milliseconds. Is there an easy way to find how many milliseconds there are until a certain time (hh:mm) or do I just have to calculate it mathematically?
Thanks!
Save your current time in milliseconds as
Calandar calendar = Calendar.getInstance();
Long currenttime = calendar.getTimeInMillis();
Long settime= <your set time in milliseconds>;
Here you can calculate the difference as follows:
Long differencetime = settime - currenttime;
int dif=(int)differencetime/1000;
Here you can set the time in calendar:
calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) + dif);
Here you can set the alarm for the settime.
AlarmManager alarmManager1 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager1.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi1);
Check out the first argument for AlarmManager.set(): With RTC/RTC_WAKEUP, you can specify a fixed time rather than an elapsed time.
That said, if you need to use the elapsed time, it's pretty trivial to calculate the number of milliseconds that need to elapse. Worst case, you could use the Calendar and/or Date classes.
Date now = new Date(), b = new Date(year, month, day, hour, min);
b.getTime() - a.getTime();
And here's another way to get the time in milliseconds to a certain time:
Calendar c = Calendar.getInstance();
c.set(c.YEAR, c.MONTH, c.DAY_OF_MONTH, 17, 1, 0); // 5:01 pm
long alarmTime = c.getTimeInMillis();
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmNotification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, alarmTime, 1000 * 60 * 60 * 24, pendingIntent); // Millisec * Second * Minute * Hour // Same time every day
RTC_WAKEUP allows the alarm to still activate when the phone is asleep. Use RTC if you want to wait until the user wakes up the phone themself.
Use am.set() if you don't want the alarm to repeat
Let me know if this helps.