Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Schedule a work on a specific time with WorkManager

WorkManager is a library used to enqueue work that is guaranteed to execute after its constraints are met.

Hence, After going though the Constraints class I haven't found any function to add time constraint on the work. For like example, I want to start a work to perform at 8:00am (The work can be any of two types OneTimeWorkRequest or PeriodicWorkRequest) in the morning. How can I add constraint to schedule this work with WorkManager.

like image 251
S Haque Avatar asked May 16 '18 06:05

S Haque


People also ask

How do I run a WorkManager at a certain time?

You can schedule a work, with onetime initial delay or execute it periodically, using the WorkManager as follows: Create Worker class: public class MyWorker extends Worker { @Override public Worker. WorkerResult doWork() { // Do the work here // Indicate success or failure with your return value: return WorkerResult.

When would you use a WorkManager?

Use WorkManager for reliable workWorkManager is intended for work that is required to run reliably even if the user navigates off a screen, the app exits, or the device restarts. For example: Sending logs or analytics to backend services. Periodically syncing application data with a server.

How do you implement a WorkManager?

To get started using WorkManager, first import the library into your Android project. Once you've added the dependencies and synchronized your Gradle project, the next step is to define some work to run.

Does WorkManager work in doze mode?

Another nice feature of WorkManager is that it respects power-management features so that if a job is scheduled to run at a defined time and the device is in Doze at that time, WorkManager will try to run the task during a maintenance window if the constraints are met or after Doze is lifted.


2 Answers

Unfortunately, you cannot schedule a work at specific time as of now. If you have time critical implementation then you should use AlarmManager to set alarm that can fire while in Doze to by using setAndAllowWhileIdle() or setExactAndAllowWhileIdle().

You can schedule a work, with onetime initial delay or execute it periodically, using the WorkManager as follows:

Create Worker class:

public class MyWorker extends Worker {     @Override     public Worker.WorkerResult doWork() {          // Do the work here          // Indicate success or failure with your return value:         return WorkerResult.SUCCESS;          // (Returning RETRY tells WorkManager to try this task again         // later; FAILURE says not to try again.)     } } 

Then schedule OneTimeWorkRequest as follows:

OneTimeWorkRequest mywork=         new OneTimeWorkRequest.Builder(MyWorker.class)         .setInitialDelay(<duration>, <TimeUnit>)// Use this when you want to add initial delay or schedule initial work to `OneTimeWorkRequest` e.g. setInitialDelay(2, TimeUnit.HOURS)         .build(); WorkManager.getInstance().enqueue(mywork); 

You can setup additional constraints as follows:

// Create a Constraints that defines when the task should run Constraints myConstraints = new Constraints.Builder()     .setRequiresDeviceIdle(true)     .setRequiresCharging(true)     // Many other constraints are available, see the     // Constraints.Builder reference      .build(); 

Then create a OneTimeWorkRequest that uses those constraints

OneTimeWorkRequest mywork=                 new OneTimeWorkRequest.Builder(MyWorker.class)      .setConstraints(myConstraints)      .build(); WorkManager.getInstance().enqueue(mywork); 

PeriodicWorkRequest can be created as follows:

 PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 12, TimeUnit.HOURS)                                    .build();   WorkManager.getInstance().enqueue(periodicWork); 

This creates a PeriodicWorkRequest to run periodically once every 12 hours.

like image 141
Sagar Avatar answered Sep 18 '22 15:09

Sagar


PeriodicWorkRequests now support initial delays from the version 2.1.0-alpha02. You can use the setInitialDelay method on PeriodicWorkRequest.Builder to set an initial delay. Link Here

Example of schedule at every day at 8:00 am. here I'm using joda time library for time operations.

final int SELF_REMINDER_HOUR = 8;      if (DateTime.now().getHourOfDay() < SELF_REMINDER_HOUR) {         delay = new Duration(DateTime.now() , DateTime.now().withTimeAtStartOfDay().plusHours(SELF_REMINDER_HOUR)).getStandardMinutes();     } else {         delay = new Duration(DateTime.now() , DateTime.now().withTimeAtStartOfDay().plusDays(1).plusHours(SELF_REMINDER_HOUR)).getStandardMinutes();     }       PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(         WorkerReminderPeriodic.class,         24,         TimeUnit.HOURS,         PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,         TimeUnit.MILLISECONDS)         .setInitialDelay(delay, TimeUnit.MINUTES)         .addTag("send_reminder_periodic")         .build();       WorkManager.getInstance()         .enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest); 
like image 28
Anjal Saneen Avatar answered Sep 17 '22 15:09

Anjal Saneen