Scheduling Notifications on Android with WorkManager
A simpler guide to get you up to speed
EDIT: This story has been updated to be compatible with Work 2.1.0-alpha01
.
As I promised in my previous post, I’m back with a quick, no-nonsense guide to scheduling notifications on Android. If you haven’t, I strongly recommend you read the previous article before going into this one:
Scheduling notifications is a strange territory, and over the years there have been a number of tools that people used for it, such as AlarmManager
, JobScheduler
, Firebase JobDispatcher
(for backwards compatibility), etc. They all mostly work, but they have certain issues and limitations, such as having notifications stop when the app is force closed or the device is restarted.
To resolve this mess, Google has released the WorkManager
as part of their Architecture Components, and it’s super enjoyable to use! In this article I’ll show you a simple way of using it.
The absolute first thing you need to do is to add the Work Architecture component to your build.gradle
as per these instructions:
There are three main steps to scheduling a notification:
1. Building the Worker Class
The first step is to extend the Worker
class and let it know what the actual work is that it should be doing when it triggers. We do this by overriding the doWork()
method of the Worker
class and returning a Result
.
In my example, we’re triggering a method that simply shows a notification, as per my previous guide. Since we don’t need to monitor this task, we just return a Result.success()
.
2. Building the Work Request
The second step is to build the work request that will get passed to the WorkManager
in the next step. We do this by using a OneTimeWorkRequest
since we only need to trigger the notification once. Alternatively, we could use a PeriodicWorkRequest
for recurring work.
In order to do this, we call the OneTimeWorkRequest.Builder
and pass it the name of the custom class we’ve previously defined. We can set a number of options for this request, as well as specify Constraints
to prevent the work from running if the battery or storage are low, and so on.
We have used setInitialDelay
to ensure the notification is triggered on the day of the event rather than immediately. This delay is calculated by a separate method which returns the amount of milliseconds between now and when the notification should trigger (at noon on the date of the event). Please note that this delay is not always accurate! Due to how modern Android works, your work can be delayed by a number of factors, so be aware of this for very time sensitive purposes.
We have used setInputData
to pass the event ID to the NotifyWorker class in order to include it in the PendingIntent to determine which event should be opened. To use it, we defined a new Data
object as shown above.
Finally, we have used addTag
to set a tag for this work type in order to be able to call WorkManager.getInstance().cancelAllWorkByTag(workTag);
to remove all work of this type from the queue in order to prevent duplicates. Another way of doing this will be explained at the next step.
3. Enqueueing the Work Request
Now that we’ve created everything we need to schedule the work, we can just ask the WorkManager to queue it to the list of active tasks from the system:
At this point, the WorkManager
will add the work to its queue, then determine when it can run and do the work as specified in the first step. And there you go, your notifications will now trigger on time, regardless of device restarts, app force closes, and without using a bulky service.
Please note that as of Work 2.1.0-alpha01
we need to use WorkManager.getInstance(context)
instead of WorkManager.getInstance()
, which is deprecated.
I also recommend reading Google’s guide on using WorkManager
:
I have also written a short, simple guide to using WorkManager
basics:
Thanks for reading this article. You can connect with me on LinkedIn.
I’m currently looking for a job in the Geneva area, Switzerland, so please contact me if you know someone in need of an Experienced Junior Developer with Java (Android) and JavaScript (React Native Android/iOS) experience.
If you liked this article, please hit the clap icon 👏 to show your support.