I have to perform this use case (not code , just the right usage)
The use case : I need to fetch some data from the network everyday at 00:30 . These data provide me some specific times , and one of them is around 4:30 (changes everyday by +1 minute -1 minute , depends on the server response, can't use ++ or -- logic anywhere) . On this one (4:30), I need to schedule an Alarm . What is unclear :
Should I use AlarmManager directly for this ?
Should I use WorkManager to get the time when I need to alarm and than use AlarmManager ?
Should I just use WorkManager ?
The reason why I am confused is because some blogs I have read say that is better to stick to AlarmManager if I have some work at a specific time, but still, I can do it with WorkManager
So how is this done ?
Should I use AlarmManager directly for this ?
Yes you should. AlarmManager is the best option as far as I know to handle tasks like yours and also is the safer option when dealing with doze mode. Use the first alarm to set the second alarm at a specific time.
Should I use WorkManager to get the time when I need to alarm and than use AlarmManager ?
If you want to use this approach you need to call AlarmManager and dispatch a Worker on WorkManager. The WorkManager need to run before a specific time and is not guaranteed that the Worker finish or will be executed before 4.30.
The reason why I am confused is because some blogs I have read say that is better to stick to AlarmManager if I have some work at a specific time, but still, I can do it with WorkManager
WorkManager doesn't guarantee the time of execution. It probably can do this in the future.
Should I just use WorkManager ?
No, for the reasons expressed before.
Android-Job is the short term response of your use case if you wanna use a job scheduler. Also you can see a table of features and differences if you go to the link.
Edit 17/03/2020:
Android-Job is deprecated.
Related
I have a foreground service and while it's active I want to run some events based on specific exact time that you a user previously set, it can be one time or it can repetitive every day for example.
I don't want to use AlarmManager because it triggers system events and you need some permissions for it, I have a running service anyway so why would I use something like this... So it should lifescoped to the service
I don't want to use Handler and its func postDelayed or launch and delay of Coroutines because it's like inventing a wheel, especially when you need to implement logic for repeatable events for a specific time.
So I'm looking something as local broadcast messages but with time configuration like in alarm and I could use set date/time instead of millis delay logic
I might need some more clarifying details to give better advice, but the following should give you an idea of the possible options and their pros and cons.
As much as AlarmManager might seem like a pain, it is probably your best bet for something like this, especially if the events are spread out over a longer period as the question hints (e.g. once a day). The alternative would be to use something like Handler, Coroutines, or a TimerTask inside the service. In addition to introducing the complexities of managing repeating events (as you mentioned), all of these require that the service is constantly running and presumably doing nothing other than waiting to fire an event, which is wasteful and likely not precise over a long period of time. Further, the service could be killed by the system and then you'd have to recreate all the timing logic, whereas AlarmManager scheduling is more persistent.
If your foreground service really is active doing other things for the entire duration in which you want these events to fire, or if the requirement is that the events fire if and only if the service is already active, then these options could be back on the table, but I'm not sure without more information.
If exactness is not an issue, you could potentially use OneTimeWorkRequest or PeriodicWorkRequest; see this documentation.
If your main concern with AlarmManager is using date/time scheduling instead of milliseconds, that shouldn't be an issue as most temporal classes provide easy ways to convert to milliseconds.
Overall, because of the inherit difficulty of precise scheduling, a system-based implementation like AlarmManager is best if exactness is the goal, and other options will incur an unnecessary waste of resources.
This is the use case : the user set a daily notification with a specific time. At the specified time, a network request is made to fetch some data and then a notification is displayed using the retrieved data. I am not sure whether I should use AlarmManager or WorkManager to implement this use case.
As I understand, AlarmManager is best for scheduling at a precise time. But without network, the job will fail and I prefer the job to be deferred to respect the network constraint than failing at execution. For this type of constrained work, with a guarantee of final execution, WorkManager looks like the best solution, using a OneTimeWorkRequest with an initial delay so that it is executed at the right time.
Comparing AlarmManager and WorkManager, WorkManager wins for some reasons:
1) AlarmManager starting from Kitkat, the alarms may be shifted by OS to reduce the wakeup of the device to reduce battery usage.
Check official documentation for more details.
2) Since you aren't going to define a specific timing for the notification, I mean here you're not going to use Calender for a specific time maybe 3:00 PM, use WorkManager because you have PeriodicWorkRequest in WorkManager.
Note that you aren't permitted to make PeriodicWorkRequest less than 15 mins.
Check PeriodicWorkRequest in official documentation
3) WorkManager now replaces all APIs for background jobs, JobScheduler, Firebase JobDispatcher.
4) WorkManager works perfectly with Coroutines
This is my humble opinion if you have any concerns kindly reply.
Happy coding 🤓
I have used background service in for updating tasks like playing with web server frequent times(sending Geo-Location data or send/get web data time-wise) in my android apps and also I have faced many problems(slow process, application hang) for this.
But In my current application I have used the AlarmManager followed by PendingIntents for some tasks which worked well.
So I think its good if I replace each updating tasks which use service with AlarmManager followed by PendingIntents.
Is it the right way or I am going doing a big mistake ?
All kind of suggestions are appreciable.
Thanks in advance.
Services and alarms scheduled with AlarmManager serve different but complementary purposes at times. When you schedule an alarm with one of the set methods, the alarm will be triggered at the specified time and you should handle it on a BroadcastReceiver. This means that your handling has to be responsive and cannot have asynchronous operations. According to the docs:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this
function, the system considers the object to be finished and no longer
active. (...) Anything that requires asynchronous operation is not
available, because you will need to return from the function to handle
the asynchronous operation, but at that point the BroadcastReceiver is
no longer active and thus the system is free to kill its process
before the asynchronous operation completes.
In case you want to handle more complex operations, it is advised to start a service for doing so. Even if you use the more recently available goAsync() call on the receiver, you are still expected to be responsive:
This does not change the expectation of being relatively responsive to the broadcast (finishing it within 10s)
So it ultimately depends on what you are trying to achieve, when to use each of these or combine their use.
I don't tell that using Alaram Manager is a big mistake..
Right now to run the background services there are only few options upon which the easy and partially reliable one would be AlarmManager.
Though sometimes the Alarm Manager is not 100% reliable on looking into other categories for doing these operations (like Asynchronous Thread and delay looping techniques) are much more complex and not that much reliable to do the background services.
When we compare the pros and cons of the techniques needed for background services AlarmManager wins the race.
I prefer AlarmManager would be the good option for these kind of background services upon thinking the options open right now to complete the tasks in background.
Hope that Google will comeup with a better solution to handle the background services.
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
I want to replace the Thread.sleep(time) calls in my code with alarms set with AlarmManager. How can I return to the proceeding code after the alarm has elapsed. It looks like I use a PendingIntent but how to I point it back to the proceeding code after the time has elapsed?.
Well, it depends on what values you have for time. If you are sleeping for 100ms, you definitely don't want to use AlarmManager, as piotrpo suggests. However, if you are sleeping for several minutes, then AlarmManager is appropriate.
AlarmManger and PendingIntents impose big overheads, so be careful with using them.
Alarm manager is not designed to something like that. .sleep() is also not good. Please read about Timer and Handler classes.