Reputation: 6035
I am building a functionality that will allow merchants to set the schedule of their business. Such functionality would automatically change the variable open
to true
and false
accordingly to the times the merchant set in each day of the week. Therefore, there would be a total of 14 possible different times.
I am trying to build a recurrent background task that would accomplish such a thing using WorkManager, the new Android Architecture Components library.
val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
.setInputData(Data.Builder().putBoolean("isStart", true).build())
.setScheduleRequestedAt(diff_time, TimeUnit.MILLISECONDS)
.addTag(weekdays[index])
.build()
It's giving me the following APILibraryException error though:
Builder.setScheduleRequestedAt can only be called from within the same library group
My questions:
1) Is it setScheduleRequestedAt
the right method to call if I want to delay the scheduling by diff_time
?
2) If so, how can I solve this problem?
PS: diff_time
is the difference, in milliseconds, to each of the corresponding hours of each day set by the user. Example: Monday-Friday = 08:00, Sat-Sun= 10:00.
Upvotes: 12
Views: 12866
Reputation: 6496
Since WorkManager v2.1-alpha02 it is now possible add an initial delay to a PeriodicWorkRequest
. Now your call became simply:
val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
.setInputData(Data.Builder().putBoolean("isStart", true).build())
.setInitialDelay(diff_time, TimeUnit.MILLISECONDS)
.addTag(weekdays[index])
.build()
Note because the setInitialDelay
has been introduced in the parent class, WorkRequest
, this introduced a binary change moving from v2.0 to v2.1 for the OneTimeWorkRequest#setInitialDelay()
method. This means that to use the new library you need to recompile the project when upgrading from v2.0.
It's not possible to delay the first run of a periodic task with WorkManager.
Your best option is to use a OneTimeWorker with the delay that you want and from there you can enqueue your periodic worker with the period you want.
Note: because of how the minimum interval works, you cannot build a periodic work request that is executed at a recurring time, e.g. every day at 4:00 AM. You can specify a 24 hours repeat interval, but this can get the worker executed at 4:05AM the first day, 6:00AM the second, 6:10 AM the third day and so on.
If you need to execute a worker at the same time every day, your best option is to use a OneTimeWorkRequest
with an initial delay:
OneTimeWorkRequest save = new OneTimeWorkRequest
.Builder(SaveImageToFileWorker.class)
.setConstraints(constraints)
.setInitialDelay(24, TimeUnit.HOURS)
.addTag(TAG_OUTPUT)
.build();
When the worker has been completed, you can reschedule it with a Delay so that it is going to be fired at the correct time (the exact time that the worker is going to be executed depends on the constraints that you’re using when creating the work request).
Upvotes: 19
Reputation: 6621
You need to update the work manager library version to 2.1.0-alpha03. In the version WorkManager provides the functionality to add initial delay in task.
Then you need to use the method setInitialDelay(). Following is the implementation to use the same in a way to achieve specific time trigger work:
long initialDelayInSeconds = (futureSpecificTime - System.currentTimeInMills()) / 1000;
PeriodicWorkRequest workRequest =
new PeriodicWorkRequest.Builder(WorkerClass.class, interval, TimeUnit.SECONDS)
.setConstraints(workRequestConstraints)
.setInputData(inputData)
.addTag(TAG_TASK)
.setInitialDelay(initialDelayInSeconds, TimeUnit.SECONDS)
.build();
Upvotes: 2
Reputation: 3219
In the new version of Work manager (Version 2.1.0-alpha02 released on May 16, 2019) PeriodicWorkRequests now support initial delays. You can use the setInitialDelay method on PeriodicWorkRequest.Builder to set an initial delay.
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
WorkerReminderPeriodic.class,
24,
TimeUnit.HOURS,
PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,
TimeUnit.MILLISECONDS)
.setInitialDelay(1, TimeUnit.HOURS)
.addTag("send_reminder_periodic")
.build();
WorkManager.getInstance()
.enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest);
Upvotes: 1