Android beginner here:
i'm writing a pills' reminder app using alarmManager, but i was wondering if i need to implement a daily scheduler and a database to store the alarms that don't need to set off today, or does the alarmManager do everything by itself, avoiding excessive performance issues and battery drain? i'm asking it because, let's say that we have 30 alarms per 30 pills every week, i think that having all the alarms "ticking" when i only need to take a couple of pills a day is very expensive.
I tried to read the documentation but it's seem very generic.
thank you
If you really want to use AlarmManager to set repeating reminders, the Android Developer Docs recommends AlarmManager.setInexactRepeating() which allows you to set intervals like AlarmManager.INTERVAL_DAY to repeat everyday and synchronizes repeating alarms from multiple apps to fire at the same time. If you want to consider other options instead of AlarmManager you should watch this talk from Joanna Smith https://www.youtube.com/watch?v=7maNuWjL3Wc
Related
I have to update Data in my App every 24 hours at 2 am.
Currently, I have an Alarm via the AlarmManager which sends an alarm every 24 hours with the setRepeating method.
In the past I have experienced some unreliabilities with the timing of the alarm, so I was experimenting with an intent-filter and Intent.ACTION_TIME_TICK.
My Question:
What is the difference between setting a repeated alarm every 24 hours and using an intent-filter which gets its information from the system?
You should absolutely not do anything with ACTION_TIME_TICK. Nor would it be reliable if you tried- it would only work while your app is running, and if you're backgrounded you will be killed for resources. The correct answer here is actually JobScheduler or WorkManager, depending on the nature of what you're doing. Most likely WorkManager. However if you were worried about the reliability of timing of an alarm, you probably are thinking about your problem wrong. Unless you have a VERY niche use case, a bit of inaccuracy in downloading a nightly update is generally ok. In fact it may even be welcome, to spread the load out on the server. Your inaccuracy of dl time is likely due to Doze, which is a mechanic your use case should likely account for (Doze is a power saving mode where it reduces the frequency of timed events running when the screen is off).
I am implementing a widget that checks on-line train departure times between every minute and every hour, depending on the time of day.
Calling the service with
manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() - 10000, 60000, pendingIntent)
works fine, but for debugging I would like to reduce the interval to about 10 seconds which cannot be done because of the 1-minute limit in more recent versions of Android. Clearly, I don't care about battery life in the emulator.
As far as I understand, using an Hander/Timer is not an option, because it required the task to be in the foreground. Is a visible widget "in the forground"?
What is the recommended practice in this case?
you actually have to tasks
configure the alarmmanager to add/remove trigger events via intents
interprete the events with intents in a service
If you seperate both you can easily create a very simple gui/activity that does the same as the alarmmanager would do when being triggerd and that you can debug:
* onSendButtonClick: create and send pendingIntent
for the alarmmanager-handling i would implement logging into a text file each time alarmmanager is added/removed/triggered.
Be prepared that newer android versions may postpone alarmmanager events to save energy until the device is already active and that intervals less than 15 minutes may not work.
you may also need on_boot_complete to reconfigure alarmmanager after device-shutdown
What is the best way to implement repeating alarm in my android application? Every user selects a specific time and I want to notify them when this time approaches on daily bases. I have come across this, but I am wondering whether this is the best way?
The alarm manager should meet your needs. There is no better way except for maybe having a server ping your client.
Since android really doesn't like things that repeat on a predictable interval, and since recent versions don't let you repeat on an exact fixed interval anyway, you'll need to schedule the alarm at the time you want, and then when that alarm fires, schedule a new one for the next day at the time you want.
use
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarm_time,
intervel, pendingIntent);
in your activity
What are the parameters of the following:
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, alarmIntent);
And of the following:
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
What is the difference and also how are the two different in terms of functionality?
Both examples schedule a repeating alarm that will send the given alarmIntent. On both cases, the first time it is sent will be immediate (calendar.getTimeInMillis() returns the current time). On both cases, the device will be woken up when the alarm needs to be sent (as evident by AlarmManager.RTC_WAKEUP).
There are two differences between these calls. The simpler one is that the intent will be sent every fifteen minutes on the first call, and every day on the second call (as you can see in the third parameter). The more complicated difference is the function call itself: setRepeating will schedule the first alarm for exactly every fifteen minutes; setInexactRepeating will schedule the second alarm for approximately every 24 hours, meaning it might deviate from that interval - with the advantage of consuming less power.
Do notice that this has changed in API 19, where these two calls are synonymous. See this guide, and this API documentation.
Decide how precise your alarm needs to be
Choosing the alarm type is often the first step in creating an alarm. A further distinction is how precise you need your alarm to be.
For most apps, setInexactRepeating() is the right choice. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time. This reduces the drain on the battery.
For the rare app that has rigid time requirements as example, the alarm needs to fire precisely at 4:00 p.m. everyday then use setRepeating().
Reference: Decide how precise your alarm needs to be
To augment previous answers, there are a number of other best practices to consider when using repeating alarms, particularly inexact alarms requested using setInexactRepeating().
Alarm Type
Non-WAKEUP alarms are better than WAKEUP alarms from a power management perspective. Using the former your alarm may fire late, but it will still fire either when the device is woken by the user, or when another wakeup alarm fires. Using WAKEUP alarms will wake the device out of sleep, consuming additional battery and potentially causing other inexact alarms to fire that have been delayed that could otherwise have been delayed longer (reducing the batching power-saving benefits that inexact alarms provide).
Prefer alarms using the ELAPSED timebase rather than the RTC timebase. The former are more likely to have a more random distribution across devices than RTC alarms, which reduces the risk of network congestion and on the server if the alarm is triggering some sort of poll. Phones running Gingerbread (or older) suffer from a bug whereby RTC inexact alarms have a tendency to align closely to the real-time clock, e.g. approximately 30s past each quarter of an hour. ELAPSED alarms don't suffer from this bug on these earlier platform versions. Even if your alarm doesn't trigger any network activity, remember that if it is a wakeup alarm it may trigger other alarm non-wakeup intents that may hit the network.
Timebase
Be careful to specify the requested start time in the correct time domain for the alarm type. Failure to do this can result in alarms being set in the past (they fire right away) if setting an RTC alarm with an ELAPSED timebase or far in the future if setting an ELAPSED alarm using the RTC timebase. You can check what alarms an app has scheduled using dumpsys alarm via the adb shell.
Interval
Specifying an inexact alarm interval of anything other than the interval constants defined in the AlarmManager API is redundant on SDK <19: they will be scheduled as exact not inexact alarms, losing all the power-saving benefits that inexact alarms provide.
Edit: here's further explanation of the bug relating to gingerbread and honeycomb 3.0 devices: https://code.google.com/p/android/issues/detail?id=31550
setRepeating is more accurate and setInexactRepeating is for saving battery but no accurate , setInexactRepeating is good for maintenance in background for example and setRepeating is necessary for example for alarm clock .
Use setInexactRepeating() is used when app is not seriously used to required for example wake up early in the morning . if Alarm wake up approximately that time there is no any life dangeous.
like medicine pills app where highly critical patient use that app to reminde nurse or doctor staff the is compulsory to use setRepeating().
When you use setInexactRepeating()
then Android synchronizes repeating alarms from multiple apps and fires them at the same time(once). This reduces the total number of times the system must wake the device.
thus reducing drain on the battery.
repeating alarms are inexact. Note that while setInexactRepeating() is an improvement over setRepeating() also
it can still overwhelm a server if every instance of an app hits the server around the same time. Therefore, for network requests, add some randomness to your alarms.
Hi I need to set AlarmManager to run a reminder for me to take medication. I need to repeat it by custom amount of days and custom amount of times to take in the day.
So is there an efficient way to set the AlarmManager or CommonsWare's Implementation of the AlarmManager to remind me "twice a day starting at 9AM for the next 5 days" to remind me to take medication? Pls advice and tnx in advance for any constructive help in sample code and in relevant tutorials.
I haven't looked into Mark's AlarmManager implementation, but there is no way, in general, to get the bare AlarmManager to do what you are trying to do. You can schedule a single alarm, at a specific time, or a repeating alarm, that repeats at fixed intervals. If you want something that handles complex schedules like the one you describe, you'll have to write or find code that does it.
You want to use a PendingIntent with the AlarmManager. The idea is to schedule the pendingIntent with the alarmManager, have that trigger an intentService or broadcast, setup another pendingIntent with the alarmManager for the next desired event. You want to keep in mind that you'll need the BOOT_RECEIVED permission in case the user reboots their device. I have complex scheduling in Audio Control and this is exactly what I do.
Here is a pretty decent tutorial of what I mean:
http://android-er.blogspot.com/2010/10/simple-example-of-alarm-service-using.html
You need to schedule an alarm to the next time you want to take the medicine - according to your algorithm (for example if its twice a day, and you got to the pending intent callback for the first time today, then schedule the next alarm to start after [6,7,8,9,10...] hours).
You will need to save both last time of the alarm launch and the user settings in shared prefs/file/DB.
You need to handle process down (android killed it or the device was rebooted). In the case of device reboot you should use the boot receiver to start your service, but you need to remember that from android 3.1 the user has to use at least one time the GUI in order for you to intercept the boot completed receiver. The boot completed receiver should look when was the last time that the alarm launched, and according to the user settings set the next alarm launch.
In the case of android killed your service, you will need to make research, i can't help here.
see example