18

How to properly use the new WorkManager from Android Jetpack to schedule a one per day periodic work that should do some action on a daily basis and exactly one time?

The idea was to check if the work with a given tag already exists using WorkManager and to start a new periodic work otherwise.

I've tried to do it using next approach:

public static final String CALL_INFO_WORKER = "Call worker";

...

WorkManager workManager = WorkManager.getInstance();
List<WorkStatus> value = workManager.getStatusesByTag(CALL_INFO_WORKER).getValue();
if (value == null) {
    WorkRequest callDataRequest = new PeriodicWorkRequest.Builder(CallInfoWorker.class,
                24, TimeUnit.HOURS, 3, TimeUnit.HOURS)
                .addTag(CALL_INFO_WORKER)
                .build();
    workManager.enqueue(callDataRequest);
}

But the value is always null, even if I put a breakpoint inside the Worker's doWork() method (so it is definitely in progress) and check the work status from another thread.

Gaket
  • 6,533
  • 2
  • 37
  • 67

3 Answers3

18

You can now use enqueueUniquePeriodicWork method. It was added in 1.0.0-alpha03 release of the WorkManager.

Greg Dan
  • 6,198
  • 3
  • 33
  • 53
16

You are looking for enqueueUniquePeriodicWork

This method allows you to enqueue a uniquely-named PeriodicWorkRequest, where only one PeriodicWorkRequest of a particular name can be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

Sample code

public static final String TAG_MY_WORK = "mywork";

public static void scheduleWork(String tag) {
    PeriodicWorkRequest.Builder photoCheckBuilder =
            new PeriodicWorkRequest.Builder(WorkManagerService.class, 1, TimeUnit.DAYS);
    PeriodicWorkRequest request = photoCheckBuilder.build();
    WorkManager.getInstance().enqueueUniquePeriodicWork(tag, ExistingPeriodicWorkPolicy.KEEP , request);
}

You get two types of ExistingPeriodicWorkPolicy

KEEP

If there is existing pending work with the same unique name, do nothing.

REPLACE

If there is existing pending work with the same unique name, cancel and delete it.

Community
  • 1
  • 1
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
  • Thx, when the question was asked, that was not part of the API. And when it appeared, the resolved answer was given. – Gaket Nov 24 '18 at 10:36
  • I tried above periodic. its working fine at once only, when its changing next date, its not triggering. tried with 2.3.0-beta02 – harikrishnan Dec 24 '19 at 10:52
1

Eventually, I understood, that the problem lies in the way how the LiveData is used. Because there are no observers, there is no value inside.

The problem with using just the PeriodicWork is that it doesn't ensure the uniqueness of the work you want to do. In other words, it is possible to have many works that will be active simultaneously firing more times than you need.

Gaket
  • 6,533
  • 2
  • 37
  • 67
  • I want show notification once per day i tried periodicwork.seems its not working. PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 24, TimeUnit.HOURS); .It showing one day only after that its not showing and also if app is running background it will show correctly.I called workrequest in application class – Lavanya Velusamy May 16 '18 at 03:35
  • 1
    I haven't been able to check it in 24-hours length but my 15-minutes tests went well, even after the phone restart. – Gaket May 16 '18 at 04:41
  • Can you share your code for 15 mins...I tried this PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 5, TimeUnit.SECONDS,5,TimeUnit.SECONDS); for test...To run every 5 seconds and also what is the first time and sec time interaval meaning? – Lavanya Velusamy May 16 '18 at 05:14
  • PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 5, TimeUnit.SECONDS,5,TimeUnit.SECONDS); this code runs first 5 sec continuosly after that it didnt – Lavanya Velusamy May 16 '18 at 05:21
  • @LavanyaVelusamy Ideal Min time for periodic requests is 15 minutes (mentioned it in the IO 18). – Srikar Reddy May 16 '18 at 07:54
  • @Srikar Reddy, it is not ideal, it is minimal :) You can check `PeriodicWorkRequest` class and there is a constant: `public static final long MIN_PERIODIC_INTERVAL_MILLIS = 900000L;` – Gaket May 16 '18 at 17:31
  • PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 20, TimeUnit.MINUTES); I given like this..But its not running periodically – Lavanya Velusamy May 18 '18 at 06:37
  • https://stackoverflow.com/questions/50415756/android-workmanager-api-for-running-daily-task-in-background pls ans this – Lavanya Velusamy May 19 '18 at 01:53
  • On Android developers they do not have mentioned about 15 min minimal time. – Maya Mohite Jun 04 '18 at 08:59
  • @MayaMohite, probably, it is a documentation bug, you can check out the source code. – Gaket Jun 04 '18 at 12:33
  • @LavanyaVelusamy I have the some problem, can you find a solution or it's still buggy? I created a 20 min periodic work request but it's only runs once when I started to app – ysfcyln Aug 20 '18 at 09:12