Set AlarmManager only with TimePicker in Xamarin.Android, alarm starting instantly [duplicate] - android

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.

Related

AlarmManager time not being set correctly

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

Android multiple alarms not working

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.

Disabling default AlarmClock alarm

I've set an alarm in the default AlarmClock app. How to disable that previously set alarm? I didn't use AlarmManager for this.
Intent alarm = new Intent(AlarmClock.ACTION_SET_ALARM);
int hour = Integer.parseInt(message.substring(11,13));
int minutes = Integer.parseInt(message.substring(14,16));
if((message.substring(17,19).equalsIgnoreCase("AM") || message.substring(17,19).equalsIgnoreCase("PM")))
{
if(message.substring(17,19).equalsIgnoreCase("AM"))
{
alarm.putExtra(AlarmClock.EXTRA_HOUR, hour);
}
else
alarm.putExtra(AlarmClock.EXTRA_HOUR, hour+12);
alarm.putExtra(AlarmClock.EXTRA_MINUTES, minutes);
alarm.putExtra(AlarmClock.EXTRA_MESSAGE, name+": "+message.substring(20));
}
startActivity(alarm);
In the string message, I'm taking the hour, minutes and AM/PM from the user.
I think you don't need the answer for this question until now but I think some other guys will be need...
Please try :
Intent itentChangeAlarm = new Intent("android.intent.action.ALARM_CHANGED");
alarmChanged.putExtra("alarmSet", enabled);
context.sendBroadcast(itentChangeAlarm);

MonoDroid - Daily scheduled service using alarm manager?

I am trying to schedule a service to run daily at a user specified time. I am using a timepicker to give the user control over what time of day the service is run.
Each time the user changes the time of day for the service to run I am updating the alarm manager.
Here is my code to do this:
void RescheduleOpeningRatesRetriever (string strTime)
{
var i = new Intent (this.ApplicationContext, typeof (OpenRatesService));
var src = PendingIntent.GetService (this.ApplicationContext, 0, i, PendingIntentFlags.UpdateCurrent);
var am = (AlarmManager)this.ApplicationContext.GetSystemService (Context.AlarmService);
var hour = TimePickerPreference.GetHour (strTime);
var minute = TimePickerPreference.GetMinute (strTime);
var cal = Java.Util.Calendar.GetInstance (Java.Util.TimeZone.Default);
cal.Set (Java.Util.CalendarField.HourOfDay, hour);
cal.Set (Java.Util.CalendarField.Minute, minute);
am.SetRepeating (AlarmType.RtcWakeup, cal.TimeInMillis, AlarmManager.IntervalDay, src);
}
I am not 100% sure if the code is scheduling the service to run properly as I have had mixed results from my tests.
The problem that I am experiencing now is each time I re-schedule the service to run with the above code, the service is started instantly.... I don't want to start the service until the configured time of day.
How can I schedule and update the service to run at a specified time of day without running the service instantly upon scheduling it with the alarm manager?
If the time for which you are setting the alarm is in the past then the alarm will goes off instantly. so first check whether the time is in past, if it is then set it for next day.
like::
Calendar rightNow = Calendar.getInstance()
if( cal.after( rightNow ) )
{
am.SetRepeating (AlarmType.RtcWakeup, cal.TimeInMillis, AlarmManager.IntervalDay, src);
}
else
{
cal.roll(Java.Util.CalendarField.DAY_OF_MONTH, 1);
SetRepeating (AlarmType.RtcWakeup, cal.TimeInMillis, AlarmManager.IntervalDay, src);
}

Time in Milliseconds Alarm

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.

Categories

Resources