Schedule a Work on a Specific Time with Workmanager

Schedule a work on a specific time with WorkManager

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.

How to enqueue WorkManager OneTimeWorkRequest at specific time

I think i have found an easy and working solution.
It works 100%.

We have to get current time in milliseconds and required specific time to trigger it in milliseconds then you have to calculate specific time - current time.

I have my solution (working code below) :

Data d = new Data.Builder()
.putInt(IntentConstants.SCHEDULE_ID, scheduleData.getScheduleID())
.build();

long currentTime= System.currentTimeMillis();
long specificTimeToTrigger = c.getTimeInMillis();
long delayToPass = specificTimeToTrigger - currentTime;

OneTimeWorkRequest compressionWork =
new OneTimeWorkRequest.Builder(ScheduleWorker.class)
.setInputData(d)
.setInitialDelay(delayToPass, TimeUnit.MILLISECONDS)
.build();

WorkManager.getInstance().enqueue(compressionWork);

Main Logic is in the delayToPass = currentTime (in Millis) - specificTimeToTrigger (in Millis)

WorkManager need to work only in between particular time interval, how to use work manager constraints ? Work manager example

You cannot stop the Workmanager for some period of time.

Here is the trick just add this condition in doWork() method

Basically you need to check the current time ie is it evening or night if yes dont perform your task.

Calendar c = Calendar.getInstance();
int timeOfDay = c.get(Calendar.HOUR_OF_DAY);
if(timeOfDay >= 16 && timeOfDay < 21){
// this condition for evening time and call return here
return Result.success();
}
else if(timeOfDay >= 21 && timeOfDay < 24){
// this condition for night time and return success
return Result.success();
}

I want to schedule notification on specific date should i use workmanager?

WorkManager is intended for tasks that are deferrable - that is, not required to run immediately and required to run reliably even if the app exits or the device restarts. For example:

  • Sending logs or analytics to backend services
  • Periodically syncing application data with a server

Alarms (based on the AlarmManager class) give you a way to perform time-based operations outside the lifetime of your application. For example, you could use an alarm to initiate a long-running operation, such as starting a service once a day to download a weather forecast.

Alarms have these characteristics:

  • They let you fire Intents at set times and/or intervals.
  • They operate outside of your application, so you can use them to
    trigger events or actions even when your app is not running, and even
    if the device itself is asleep.

So for your requirement, you should be using an AlarmManager instead of WorkManager as you only need to deliver a notification.



Related Topics



Leave a reply



Submit