How does Android handle alarms set for the past - java

In my application I want to trigger a recurring alarm at about a specified time to check for some conditions and notify the user if necessary.
I'm using the following code to schedule the alarm:
Calendar cal = ...;
...
mAlarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mAlarmIntent);
I now noticed (because I accidentially had the wrong day in cal) that the alarm would be triggered right away if cal was some date/time in the past.
So let's say it is 2016-09-20 18:00:00 and I schedule the alarm for 2016-09-20 17:00:00. I'd get a notification right away (or a couple of seconds after scheduling the alarm). This does not happen if I schedule the alarm for a future time like 2016-09-20 18:15:00.
So my questions are:
Will Android always catch up on the missed alarm?
The alarm is scheduled to repreat daily. Will it then repeat at 17:00:00 tomorrow or will it be at 18:00:00, because that was when the alarm was last triggered?

Will Android always catch up on the missed alarm?
if the set time is in past then android trigger alarm as soon as possible. check the docs
The alarm is scheduled to repreat daily. Will it then repeat at
17:00:00 tomorrow or will it be at 18:00:00, because that was when the
alarm was last triggered?
Next time it will be triggered on time
Additional Info : if the use clear app data or forced close your app from application manager then alarm won't trigger until user open your app again plus reboot can also cause this.

Related

Scheduling a notification?

Is there any way to schedule a notification to appear at a specific time?
I am developing an app that reminds a user to change their bandage every 6/12 hours and I wish to send a notification to the user 6/12 hours after they confirm that they have applied the bandage.
Is there any way to do this? I have tried to implement the alarmManager Class however every example I have found uses a specific time of the day as opposed to 6/12 hours after an event.
I have an app which checks whether to show a notification every 24 hours. You can change it to whatever interval you would like.
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
// Create a PendingIntent which AlarmManager would raise.
// You should have a BroadcastReceiver to receive the intent and send a push notification.
setInexactRepeating(
AlarmManager.RTC_WAKEUP,
startAt.toEpochSecond() * 1000,
intervalInMillis,
pendingIntent
)
}
startAt -> Epoch when your alarm should start working (preferably in future). If this is in past, it will immediately boradcast the intent.
intervalInMillis -> Interval in milliseconds. For your case this should be 6 hours.
If your app requires different alarms (notifications) at 6 and 12 hours, I would still go with 6 hours or even 3 hours as the interval. When the broadcast is received, you should check if the app is supposed to send a notification or not. If not, don't do anything.
Read more about Scheduling repeating alarms.
Note: AlarmManager is affected by doze mode and you need to reset all your alarms after the phone restarts. Clubbing this with WorkManager would be ideal. But this should get you started.
Schedule tasks with WorkManager
https://developer.android.com/topic/libraries/architecture/workmanager/
Previously firebase-jobdispatcher-android was working fine now google introduced new WorkManager for scheduling task.
Here is a simple implementaion
http://thetechnocafe.com/how-to-use-workmanager-in-android/

Android calendar provider schedules clock alarm automatically

I am making an activity which gets the next alarm clock with the method getNextAlarmClock(). It works perfectly and shows as expected the earlier alarm clock set in the system (in my case from the stock MIUI clock app).
Now comes the problem:
I noticed that if I set the alarm clock for the next day that the alarm is set for today's midnight. But I don't have any alarm set before tomorrow, and this repeats every day (one day is midnight, one day is 7:50pm, one day is 11:50 pm) but at that hour nothing happens.
So being totally confused by my phone behavior I connected to adb shell and executed dumpsys alarm command. I found these lines in the output:
Batch{38cd120 num=1 start=298318940 end=298318940 flgs=0x3}:
RTC_WAKEUP #0: Alarm{5d9a2c9 type 0 when 1510599024750 com.android.providers.calendar}
tag=*walarm*:com.android.providers.calendar.SCHEDULE_ALARM
type=0 whenElapsed=+5h12m31s451ms when=2017-11-13 19:50:24
window=0 repeatInterval=0 count=0 flags=0x3
Alarm clock:
triggerTime=2017-11-13 19:50:24
showIntent=null
operation=PendingIntent{db9bdce: PendingIntentRecord{b3ec4ef com.android.providers.calendar broadcastIntent}}
So it seems that the android calendar provider fires an alarm clock every day, but no memos or events are in the calendar.
My questions are:
Why the calendar provider fires this alarm? and why it is an alarm clock instead of a simple alarm?
How can i remove all the future calls to this alarm?

Should I use AlarmManager or JobScheduler for this?

I have a table in my database where each row describes a schedule. For example:
ID | CODE | DAY | TIME
___________________________________
1 1 Mon 8
2 27 Wed 15
In other words, every Monday at 8 am, the function corresponding to code 1 is called. Every Wednesday at 3 pm, the function corresponding to code 27 is called, etc.
What's the right way to call ALL these tasks at their proper times in Android? I've seen both AlarmManager and JobScheduler but I don't know which one is more appropriate to use for something like this.
I don't need the times to be super precise (having the events trigger +/- a few seconds or even minutes from the designated times is not a huge deal), but I do need them to trigger whenever possible.
Alarm Manager will be more appropriate as one way or the other what you are trying to do maps upon the requirement of creating alarms.
If you just need to trigger event with schedule without network or charge check, Alarm Manager is lightweight and working solution.
You can try this library for quick Alarm Manager implementation.
https://android-arsenal.com/details/1/4755
Use AlarmManager with setExactAndAllowWhileIdle
Be aware that on marshmallow and later, task scheduled with AlarmManager might be delayed due to Doze. The only way to get exact timing is to use setAlarmClock which might display an alarm clock icon in the status bar on some system.

Perform some action when certain time comes

I'm building an Android organizer app.
I have an Event class that has a start time and I want to trigger some action when this time comes. So, how can I constantly compare this start time with current time, to know when it comes?
Thanks!
Instead of constantly checking for current time against scheduleStartTime, you can schedule task to trigger at scheduledStartTime.
You can use either JobScheduler or AlarmManager
https://developer.android.com/reference/android/app/job/JobInfo.Builder.html
https://code.tutsplus.com/tutorials/using-the-jobscheduler-api-on-android-lollipop--cms-23562
You can set when to trigger task by specifying time difference between start time and current time in millisecond.
builder.setPeriodic(5000);
Or you can also use Alarm manager
https://developer.android.com/training/scheduling/alarms.html
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
Hope this help
You could use one of the following solutions :
Have a time and on Timer tick, you could compare your start time against the current time and trigger you action if needed.
Or, you could use a ScheduledExecutorService to schedule the task you want to archive x seconds in the future base on the current time and the start time of your Event
As you are on Android, I would recommend to do this as part of a Service.
Hope this will help.

Android setting alarm to a past date

What happens should I add an alarm but set the starting date to a past date?
Does is get executed immediately or is it put in the queue and never executed?
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startDate, repeatingValue, alarmIntent);
From documentation, if the startDate time is in the past, the alarm will be triggered immediately.
If the date is in past then alarm will trigger immediately. However you may try to use setInexactRepeating instead of setRepeating:
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startDate, setInexactRepeating , alarmIntent);
From the setInexactRepeating() docs:
Schedule a repeating alarm that has inexact trigger time requirements;
for example, an alarm that repeats every hour, but not necessarily at
the top of every hour.
Actually AlarmManager works with the current time.
So when you will set past date alarm then AlarmManager will execute
public void onReceive(Context context, Intent intent)
{
}
method.
I think the alarm is set only for hours(at least through the Android user interface), not for a particular day, this way it will start on the exact hour:minute you set.
As i can conclude from my previous experience with AlarmManager. Date that is in the past will trigger alarm immediately.
As far as I can tell, AlarmManager.set will execute now when the time is set to a past time, the documentation says as much. This sentence is missing for AlarmManager.setInexactRepeating , this alarm will not trigger when it's set for a past time, it will trigger at the next interval, starting from the given time.
AlarmManager.set and AlarmManager.setInexactRepeating are both calling setImpl, with the triggertime they got passed as parameter (checked in Android 7.1.2 sources).
--> there's no difference in both methods, if the triggertime is in the past.

Categories

Resources