AlarmManager time not being set correctly - android

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

Related

chronometer in home screen widget - wrong count down format

I have home screen widget which have one chronometer as RemoteViews item.
I need this chronometer to countdown from some time in the future. Chronometer works, but I have noticed some strange time formatings on some devices.
For example, if there is 10 minutes and 5 seconds remaining, I have following outputs:
Huawei Mate 10 Lite (Android Oreo - API 26)
-10:05
Huawei G7, with Lollipop (API 22)
00:-605 - total remaining time here is displayed as number of seconds.
My question: is there any way that I can provide my formating, so that result be same on all devices.
NOTE: I need this for chronometer in homescreen widget, not inside of an activity or a fragment.
Edit: Widget is refreshed from AlarmManager. On BroadcastReceiver I have following code to update widget.
protected void updateCountdownTimer(RemoteViews remoteViews, int index) {
Calendar calendar = Calendar.getInstance();
List<Time> timeList;
if (index == -1) {
calendar.add(Calendar.DATE, 1);
TimesProvider.getProvider().setCurrentDate(calendar);
index = 0;
}
timeList = TimesProvider.getProvider().getTimes();
Time time = timeList.get(index);
calendar.set(Calendar.HOUR_OF_DAY, time.getHour());
calendar.set(Calendar.MINUTE, time.getMinute());
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
remoteViews.setChronometer(R.id.chronometer, SystemClock.elapsedRealtime() + calendar.getTimeInMillis() - System.currentTimeMillis(), null, true);
remoteViews.setTextColor(R.id.chronometer, Color.CYAN);
}

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

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.

How to start an alarm if the mobile is switch off

In my app, I use the AlarmManager class to set an alarm. To trigger the alarm after the mobile is rebooted I have used BroadcastReceiver. All works fine and my alarm is triggered at regular intervals. Now the problem arises in this case :
Suppose my current time is 2:30 pm and I set my alarm at 2:35 pm. After that, I switch off the mobile. After an hour when I switch on my mobile, no alarm is pop-up as the time on which the alarm is set. This is happening because the current time exceeds the time on which I set the alarm. To solve this issue what should I do. I have posted my code for setting alarm in the AlarmManager class. Please help me to solve this out
public class AlarmReceiver extends BroadcastReceiver {
#SuppressWarnings("static-access")
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Intent myIntent = new Intent(context, MyAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, i, myIntent, i);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MILLISECOND, (int) Utilities.diff(NoteManager.getSingletonObject().getAlarmTime(i)));
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
}
public static long diff(Date date) {
long difference = 0;
try {
// set current time
Calendar c = Calendar.getInstance();
difference = date.getTime() - c.getTimeInMillis();
if (difference < 0) {
// if difference is -1 - means alarm time is of previous time then current
// then firstly change it to +positive and subtract form 86400000 to get exact new time to play alarm
// 86400000-Total no of milliseconds of 24hr Day
difference = difference * -1;
difference = 86400000 - difference;
}
}
catch (Exception e) {
e.printStackTrace();
}
return difference;
}
In The Manifest File
<receiver android:name=".AlarmReciever">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
better way is to store that alarm details in database and retrieve it on boot via broadcast receiver as you are saying you implemented one. once notified remove the details from the database. this way u can track all your alarms. even you can start a Service on startup and do this operation
The Alarm app in the Android does the same, if your phone is switched off and there is Alarm to ring up, It will make your phone switch On , ring the alarm and go to sleep again.
Here is the link of source of Alarm app Git_Alarm app you can download it and see how it is doing this.
and if you are doing something else in your alarm reciever then to ring Alarm up. you can basically set alarmreciever again in the phone Boot up, here is the one answer which may help you Alarm problem if phone is switched off
Edit :- one link was broken, replaced it

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