I want to schedule a notification everytime the user add a note in the database for a specific time. While there are multiple ways to do it using AlarmManager, BroadcastReceiver etc. How can it be done using WorkManager?
5 Answers
WorkManager
isn't appropriate for work that needs to happen at a particular time.
You should use AlarmManager
, and specifically AlarmManagerCompat.setExactAndAllowWhileIdle(), to get a callback at a specific time.

- 191,609
- 30
- 470
- 443
-
Is it because due to this limitation? For every alarm, we have a unique tag for WorkManager. However, sometimes, we get unexplained exception caused by WorkManager - ` java.lang.IllegalStateException: Apps may not schedule more than 100 distinct jobs` – Shuwn Yuan Tee Jun 02 '18 at 10:15
-
1@ShuwnYuanTee - that's a [known issue](https://issuetracker.google.com/issues/79497378), already marked as fixed for alpha03. You still shouldn't be scheduling hundreds of different jobs at different times in the future though. – ianhanniballake Jun 02 '18 at 13:32
-
"You still shouldn't be scheduling hundreds of different jobs at different times in the future though. " -> Thanks. May I know the reason for such advice? The reason we are reluctant to use AlarmManager is that, it doesn't have "TAG" concept. It is rather difficult to cancel a already scheduled alarm. (Different pending intent, with different extras, are treated as same) In contrast, WorkManager has TAG concept. Hence, it is rather convenient for us to cancel an already scheduled alarm. – Shuwn Yuan Tee Jun 02 '18 at 13:47
-
4@ShuwnYuanTee - a common tactic is to only schedule one alarm (the next one) and have it schedule the next alarm when it fires. Absolutely no reason to have the system keep track of a ton of alarms if you know they'll fire sequentially – ianhanniballake Jun 02 '18 at 13:50
-
2Thanks for advice. However, such tactic does have shortcoming. Missing one alarm (which I believe is quite common due to Doze feature), will cause sub sequent alarms not scheduled. – Shuwn Yuan Tee Jun 02 '18 at 13:58
-
@ianhanniballake So it should be understood that the Android SDK as of now does not have a clear way to programmatically schedule repeating tasks at pecific time intervals. – Samuel Owino Jul 23 '19 at 15:39
-
1Alarms are not triggered in few OEMs , is there any other way ?. – Manohar Mar 16 '20 at 15:22
-
@ianhanniballake AlarmManager doesn't seem to work in Android pie :( – Narendra Singh Apr 26 '20 at 10:29
-
I think this answer is outdated – Jemshit Aug 18 '20 at 09:26
-
2@JemshitIskenderov - nope, WorkManager absolutely is not the right API for running something at a particular time - WorkManager does no work while the device is dozing, which breaks any semblance of exact timing (since the device can be dozing at any time, your app can't control that part) – ianhanniballake Aug 18 '20 at 13:42
-
on the other hand AlarmManager loses everything on device boot, it needs local storage assistance – Jemshit Aug 20 '20 at 13:40
You can show notification with the help of workmanager. Workmanger can be used for scheduling single occurrence task or periodic occurrence task as well as we can schedule task at a particular time.
OneTimeWorkRequest request= new OneTimeWorkRequest.Builder(CustomWorkerClass.class)
.setInitialDelay(delayedTime, TimeUnit.MILLISECONDS)
.addTag("TAG")
.build();
'delayedTime' -> calculate time when to trigger notification
for more implementation details click here. To read more regarding workmanager click here

- 841
- 11
- 19
-
remember delayedTime is a variable where your wanted notification time substract by your current time. – Liong Oct 05 '21 at 05:31
-
It is not a good answer because WorkManager is not suitable for conditions that needs to be precise at exact time. – Emad Razavi Nov 29 '21 at 06:28
According to the Android official documentation about worker manager: "These APIs let you create a task and hand it off to WorkManager to run immediately or at an appropriate time". In my app, I set a work to be activated 20 seconds after:
// Schedule the time
val request= OneTimeWorkRequestBuilder<YourWork>().setInitialDelay(20, TimeUnit.SECONDS).build()
WorkManager.getInstance().enqueue(request)

- 352
- 2
- 13
-
Yes, the app is opened when the alarm is fired. This doesn't mean that the app become in foreground when the alarm is fired, this means that the app is opened to run the code of the Worker and then it is closed. The lifecycle of an Android Application is OnCreate, EnterForeground, enterBackground and onTerminate. In this case, the app jumps beteween onCreate and onTerminate. – Gerardo Suarez Sep 03 '18 at 22:07
It is not a good practice to do this kind of task using work manager when you want to trigger notification at particular time because work manager works for delay and async task that manage periodic or delay functionality.Still you can do this using this method which is not a good practice,
You can get calendar values like this,
val timePicker = your timepicker here
val calendar: Calendar = Calendar.getInstance()
val nowMillis = calendar.timeInMillis
and then you can set your worker for specific task as below,
calendar.set(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
timePicker.hour,
timePicker.minute)
val difference = calendar.timeInMillis - nowMillis
val alarmRequest = OneTimeWorkRequest
.Builder(AlarmWorker::class.java)
.setInitialDelay(difference, TimeUnit.MILLISECONDS).build()
WorkManager.getInstance(this).enqueue(alarmRequest)

- 316
- 2
- 9
-
I'm curious to know what happens if the difference is a negative value. Fore example, we have setInitialDelay(-10000, TimeUnit.MILLISECONDS) – Jayhymn Jan 04 '23 at 10:50
As ianhanniballake stated
WorkManager isn't appropriate for work that needs to happen at a particular time.
But this can be set in near future of the exact time, depending on the state of the battery optimization.
An workaround will be like:
// Time to show notification at
LocalDateTime timeAt = LocalDate.now().atTime(20, 0);
LocalDateTime timeNow = LocalDateTime.now();
OneTimeWorkRequest.Builder workBuilder = new OneTimeWorkRequest.Builder(NotificationWorker.class);
// I just need to set an delay here
workBuilder.setInitialDelay(Duration.between(timeNow, timeAt));
// This is just to complete the example
WorkManager.getInstance().enqueueUniqueWork(UNIQUE_WORK_SHOW_NOTIFICATION,
ExistingWorkPolicy.REPLACE,
workBuilder.build());

- 2,419
- 3
- 23
- 36