Okay, So I'm working on having an alarm that gives a notification at, lets say 3:00 PM daily, but I want this to be selectable by the user, between AM/PM, and Hours/Min freely changeable. I will probably use a TimePicker, and this is my code I have so far:
public void startAlarm() {
Intent intent = new Intent(currentDay.this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(currentDay.this,0, intent,0);
long firstTime = SystemClock.elapsedRealtime();
firstTime += 15*1000;
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firstTime,AlarmManager.INTERVAL_DAY, sender);
}
So, I figure I'm going to be using something along the lines of:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 19);
cal.set(Calendar.MINUTE, 45);
and then using
cal.getTimeInMillis()
But this doesn't work, any ideas? Thanks!
EDIT: So, long story short, I know how to get the current time, then add lets say 15 seconds to it, but I want to have a definite time that WORKS for example 5:14 PM, and everything I've tried doesn't work
As far as I can tell you are getting a Calendar instance with the current date/time and then you are adding 19 hours and 45 minutes to it, NOT setting the time of the Calendar instance explicitly to 19:45. Is that what you are meaning to do? You need to use the Calendar set() method to set an explicit time.
From the API reference for Calendar
Calendar's getInstance method returns a calendar whose locale is based on system settings and whose time fields have been initialized with the current date and time:
Calendar rightNow = Calendar.getInstance()
public abstract void add (int field, int value)
Since: API Level 1
Adds the specified amount to a Calendar field.
Parameters
field the Calendar field to modify.
value the amount to add to the field.
Throws IllegalArgumentException if field is DST_OFFSET or ZONE_OFFSET.
EDIT: To convert local time to UTC...
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 19);
cal.set(Calendar.MINUTE, 45);
int offset = cal.getTimeZone().getOffset(cal.getTimeInMillis());
firstTime = cal.getTimeInMillis() + offset;
NOTE: I haven't tried the above and there may be an easier way but it should work. It's hard for me to test stuff like this as my timezone is GMT/UTC.
Related
I am developing an app where I use an AlarmManager to schedule a time to open an Activity.
The chosen time is picked by a TimePicker.
Despite the time being the expected one when I call the method when.getTime , my activity doesn't open at the specified time.
Getting the time
int hour = tp.getCurrentHour();
int min = tp.getCurrentMinute();
MedicationReminder mr = new MedicationReminder(getApplicationContext());
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR, hour);
c.set(Calendar.MINUTE, min);
if (hour > 12) {
c.add(Calendar.HOUR, 12);
}
mr.setReminder(new Medication(name, quant_aux, time), c);
Setting alarm
Intent i = new Intent(mContext, MedicationReceiver.class);
i.putExtra("medName",medication.getName());
i.putExtra("medQuant",medication.getQuantity());
PendingIntent pi=PendingIntent.getBroadcast(mContext,0,i,0);
mAlarmManager.set(AlarmManager.RTC_WAKEUP,when.getTimeInMillis(),pi);
I tried replacing when.getTimeInMillis by 2000 and the activity opened , so the problem is not on my broadcast receiver.
Why is this happening?
Edit: I tried to schedule for the following minute and the acitivity opened.
I tried for the next 2 minutes and the activity opened with a delay of 12-15 seconds. Tried with 5 minutes and the activity didn't open
Try using setExact instead of set
...
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
https://developer.android.com/training/scheduling/alarms
public static boolean setupAlarm(String flightName, long columnId, int time,int requestCode, Context context) {
AlarmManager alarmManager;
FlightTimeObject timeObject = DataCheckingUtils.getConvertedTime(time);
try {
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context.getApplicationContext(), ProcessAlarmReceiver.class);
intent.putExtra(IntentActions.INTENT_REQUEST_CODE, requestCode);
intent.putExtra(IntentActions.INTENT_SEND_STRING_FLIGHT, flightName);
intent.putExtra(IntentActions.INTENT_SEND_FLIGHT_COLUMN_ID, columnId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent,0);
//Get calendar instance
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
//get hour
if (timeObject.getHour()!= -1) {
int hour = timeObject.getHour();
calendar.set(Calendar.HOUR_OF_DAY, hour);
}
//get minute
if (timeObject.getMinute()!=-1){
int minute = timeObject.getMinute();
calendar.set(Calendar.MINUTE, minute);
}
calendar.set(Calendar.SECOND, 0);
assert alarmManager != null;
alarmManager.setExact(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
pendingIntent);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Hello everyone. The above code gets called within a for loop, underneath.
private static void setupAlarmToFlight(ArrayList<FlightObject> flightArray, Context context) {
int numberOfAlarms = 0;
int requestCode = 0;
for (int i = 0; i < flightArray.size(); i++){
FlightObject flight = flightArray.get(i);
String name = flight.getFlightName();
long flightColumnId = flight.getColumnId();
int flightActualTime = flight.getActualArrivalTime();
int scheduledTime = flight.getFlightScheduledTime();
int timeToParse = -2;
if (flightActualTime == -2){
timeToParse = scheduledTime;
}else{
timeToParse = flightActualTime;
}
boolean alarmSet = ExtractFlightUtilities.setupAlarm(
name,
flightColumnId,
timeToParse,
requestCode,
context);
if (alarmSet){
numberOfAlarms++;
requestCode++;
}
}
Intent intent = new Intent(IntentActions.ALARM_SET);
intent.putExtra(IntentActions.INTENT_SEND_INT, numberOfAlarms);
context.sendBroadcast(intent);
}
This code basically sets alarms for different flight arrival times from an arraylist that will start a service. The first alarm always fires right on time, but the rest never fire. I even stopped the service so it would just get to the receiver, but only the first fires. I also stopped the for loop at 2-3 alarms, but nothing.
I made sure that the hours and minutes are set correctly, and used another loop that would just set alarm in one minute after each but no luck.
Any help would be greatly appreciated.
EDITED:
I tried the suggestion and still not firing the alarms.
Something interesting I noticed, when setting breakpoints, the debugger gives preview values, and the first alarm that goes off okay, it's values, such as the requestCode and the Calendar values are green. All other following alarms are red.
For the first alarm.
The request code is green.
The pending intent looks all green.
The calendar value looks all green.
For all the other alarms.
The request code is red.
The pending intent request code red:
The calendar value is red
Again thank you for your time.
Since you set exact time, it might be because you did not check if the alarm time set is not passed already. E.g. consider the current date/time is 1-Jan-2018 11:30PM. If you set alarm for 01:00AM, based on your code, the alarm will be set for 1-Jan-2018 01:00AM since you used:
calendar.setTimeInMillis(System.currentTimeMillis())
which returns 1-Jan-2018 11:30PM and the you set time to 01:00AM which change the date to 1-Jan-2018 01:00AM which is passed. In this case you should add to alarm date one day. Something like this:
/**
* adjust time and date of alarm (alarms set in some previous years, will updated to today).
* if time is passed in today, date will +1
*
* #param alarmTimeCalendar time which may need adjustments
* #return adjusted time for alarm
*/
public static Calendar adjustAlarmTime(Calendar alarmTimeCalendar) {
Calendar adjustedDateCalendar = Calendar.getInstance();
int hour = alarmTimeCalendar.get(Calendar.HOUR_OF_DAY);
int minute = alarmTimeCalendar.get(Calendar.MINUTE);
adjustedDateCalendar.set(Calendar.HOUR_OF_DAY, hour);
adjustedDateCalendar.set(Calendar.MINUTE, minute);
adjustedDateCalendar.set(Calendar.SECOND, 0);
Date currentDate = adjustedDateCalendar.getTime();
Date alarmDate = adjustedDateCalendar.getTime();
long difference = alarmDate.getTime() - currentDate.getTime();
if (difference < 0) {
adjustedDateCalendar.add(Calendar.DATE, 1);
}
return adjustedDateCalendar;
}
So after trying multiple ways of approaching the problem, I solved it by setting the alarm as only RTC and not RTC_WAKEUP. Now all the alarms are firing right on time.
Thank you all.
I'am not a new Codename One user but this is my first time to use Local notification with this framework. In my app, i have a picker to allow the user to choose a time (hour and minutes). i recevied the time which is chosen with getTime() method. Now i want my local notification to trigger at that time. What is the correct value that i need to give at the second parameter of the Display.getInstance().scheduleLocalNotification() function?
So far what I have is this sample but I don't understand how to apply it to my needs:
Display.getInstance().scheduleLocalNotification(notification, System.currentTimeMillis() + 10 * 1000, LocalNotification.REPEAT_NONE);
From the Java doc of that method
#param firstTime time in milliseconds when to schedule the
notification #param repeat repeat one of the following: REPEAT_NONE,
REPEAT_FIFTEEN_MINUTES, REPEAT_HALF_HOUR, REPEAT_HOUR, REPEAT_DAY,
REPEAT_WEEK
So you can use your Date object method getTime() to return the time in millis for that date object.
EDIT
Let's assume this is the callback for your time picker
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
Calendar date = Calendar.getInstance(); // This is the time now, so the day is set to today
date.set(Calendar.HOUR_OF_DAY, hourOfDay);
date.set(Calendar.MINUTE, minute);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.MILLISECOND, 0);
Display.scheduleLocalNotification(LocalNotification, date.getTime().getTime(), repeat);
}
Setting the second and millisecond is just to ensure the alarm goes off at the exact minute the user picked.
You can also change the day, month and year same as we changed the hour and minute.
This question already has an answer here:
Xamarin Android Alarm Manager Issue
(1 answer)
Closed 5 years ago.
I having trouble while trying to set an Exact Alarm with only a Time Picker.
I set a TimePicker with an Handler like this:
TimePicker
TPBtn.Click += delegate
{
TimePickerDialog dialog = new TimePickerDialog(this, TimeSelectedListener, DateTime.Now.Hour, DateTime.Now.Minute, true);
dialog.Show();
};
private void TimeSelectedListener(object sender, TimePickerDialog.TimeSetEventArgs e)
{
hour = e.HourOfDay;
minute = e.Minute;
DateTime dtNow = DateTime.Now;
int DayOfMonth = dtNow.Day;
int Month = dtNow.Month;
int Year = dtNow.Year;
Calendar cl = Calendar.Instance;
cl.Set(Year, Month, DayOfMonth, hour, minute, 0);
AlarmManager am = (AlarmManager)this.GetSystemService(AlarmService);
Intent intent = new Intent(this, typeof(OneShotAlarm));
intent.AddFlags(ActivityFlags.NewTask);
var source = PendingIntent.GetBroadcast(this, 0, intent, 0);
am.SetExact(AlarmType.RtcWakeup, cl.TimeInMillis, source);
Toast.MakeText(this, "Set Today: " + cl.TimeInMillis, ToastLength.Short).Show();
}
Unfortunately, when doing this the alarm is instantly played.
I also tried to use am.SetAlarmClock but I don't know how to use RTC time with it, can you help me please ?
I already read many thread like I am trying to set alarm on specific time using alarm manager but alarm intiated instantly? and Set AlarmManager from DatePicker and TimePicker
Thanks a lot.
am.SetExact(AlarmType.RtcWakeup, cl.TimeInMillis, source);
cl.TimeInMillis is called on Calendar.Instance which has not been manipulated in any way. So that means it is set to "now", hence the alarm firing immediately.
It is not exactly clear what time you want the alarm to fire, but you will need to provide the correct TimeInMillis to do so.
I would like to execute a piece of code every 24 Hours however I'm not sure how to do this.
I have some code that sets the time that I would like the cycle to start but not sure how to execute the end time
int startDay = 00; // 12am
int end = 24; // 12 pm
int hours = (end - startDay) % 24; //difference will be 24 hours
Calendar calInstanceOne = Calendar.getInstance();
// set calendar to 12 am
calInstanceOne.set(Calendar.HOUR_OF_DAY, startDay);
calInstanceOne.set(Calendar.MINUTE, 0);
calInstanceOne.set(Calendar.SECOND, 0);
calInstanceOne.set(Calendar.MILLISECOND, 0);
Do I create another Calendar instance, set to 12pm? and compare the two? Would really appreciate any insight into this.
I would like to execute a piece of code every 24 Hours
Use AlarmManager, in conjunction with either WakefulBroadcastReceiver or my WakefulIntentService. Ideally, use setInexactRepeating() on AlarmManager for INTERVAL_DAY, to allow Android to slide the actual time around to best save battery for the user.
You can use AlarmManager to make actions periodically:
Intent intent = new Intent(this, MyStartServiceReceiver.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, <24h in msecs>, pendingIntent);
Then you should register your BroadcastReceiver in the manifest and call the method you want to execute from this receiver.
First store your current time then whenever app will be open compare current time with previous store time if its greater or equal 24 hour
execute your code.
You may have several choices, let me outline the easiest one. The strategy is to simply use the system time to execute twenty four hours later:
package com.test;
import java.util.Calendar;
public class ExecuteCheck {
//Class fields
/* Number of milliseconds in a day
*
*/
private static final long C_DAY=24*60*60*1000;
//Object fields
/* Time last executed (or beginning of cycle), in milliseconds;
*
*/
private long lastExecuted = System.currentTimeMillis();
public ExecuteCheck() {
}
/** Set the current execution cycle time to now
*
*/
public void setExecutionTimeToNow() {
lastExecuted = System.currentTimeMillis();
}
/** Set the execution cycle time to be the value in the calendar argument.
* #param cal
*/
public void setExecutionTime(Calendar cal) {
lastExecuted = cal.getTimeInMillis();
}
/** Is it more than twenty-four hours since the last execution time?
* #return
*/
public boolean isTimeToExecute() {
return (System.currentTimeMillis() - lastExecuted) > C_DAY;
}
}