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?
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.
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
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)
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)
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());
© 2022 - 2024 — McMap. All rights reserved.