Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if WorkManager is scheduled already

How can I check if WorkManager is scheduled already.

Here is my code that schedule WorkManager.

public static void scheduleWork() {     PeriodicWorkRequest.Builder photoCheckBuilder =             new PeriodicWorkRequest.Builder(WorkManagerService.class, TIME_INTERVAL_IN_SECONDS,                     TimeUnit.SECONDS);     PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();     WorkManager instance = WorkManager.getInstance();     if (instance != null) {         instance.enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);     } } 

I call scheduleWork() in onCreate() of my Application class. Even I can check my service is running or not by this method. But I don't want schedule WorkManager if it is already scheduled to remove inconsistency in scheduled time.

Like

if(!workManagerIsScheduled())    {      scheduleWork();    } 

Any solutions?

like image 378
Khemraj Sharma Avatar asked Jul 31 '18 11:07

Khemraj Sharma


People also ask

How do I know if my WorkManager is running?

At any point after enqueuing work, you can check its status by querying WorkManager by its name , id or by a tag associated with it. The query returns a ListenableFuture of a WorkInfo object, which includes the id of the work, its tags, its current State , and any output data set via Result. success(outputData) .

Does WorkManager run on background thread?

Worker is the simplest implementation, and the one you have seen in previous sections. WorkManager automatically runs it on a background thread (that you can override).

What is difference between WorkManager and service?

WorkManager is not answer to all of the background tasks. E.G. You shouldn't use it for processing payments since it doesn't need to survive process death and these task needs to be executed immediately. Consider using Foreground Service. Its also not a great idea to use them for parsing data and contents of view.


2 Answers

Update

If you need to check already running work manager just because you don't want duplicate works. You can simply use 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.

So you don't need to worry about duplicacy about works.

 workmanager.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP , photoCheckWork); 
  • Where TAG is unique name by which work manager will check duplicacy.
  • You can choose between ExistingPeriodicWorkPolicy.KEEP and ExistingPeriodicWorkPolicy.REPLACE.

Orignal Post

I created this method when I did not find any.

Check if work is running by TAG

if (your_work_manager.version >= 1.0.0-alpha11)

private boolean isWorkScheduled(String tag) {     WorkManager instance = WorkManager.getInstance();     ListenableFuture<List<WorkInfo>> statuses = instance.getWorkInfosByTag(tag);     try {         boolean running = false;         List<WorkInfo> workInfoList = statuses.get();         for (WorkInfo workInfo : workInfoList) {             WorkInfo.State state = workInfo.getState();             running = state == WorkInfo.State.RUNNING | state == WorkInfo.State.ENQUEUED;         }         return running;     } catch (ExecutionException e) {         e.printStackTrace();         return false;     } catch (InterruptedException e) {         e.printStackTrace();         return false;     } } 

if (your_work_manager.version < 1.0.0-alpha11)

private boolean isWorkScheduled(String tag) {     WorkManager instance = WorkManager.getInstance();     LiveData<List<WorkStatus>> statuses = instance.getStatusesByTag(tag);     if (statuses.getValue() == null) return false;     boolean running = false;     for (WorkStatus workStatus : statuses.getValue()) {         running = workStatus.getState() == State.RUNNING | workStatus.getState() == State.ENQUEUED;     }     return running; } 

It will return true when some of its task is RUNNING or ENQUEUED.

Sample code

public static final String TAG_MY_WORK = "mywork";  if(!isWorkScheduled(TAG_MY_WORK)) { // check if your work is not already scheduled     scheduleWork(TAG_MY_WORK); // schedule your work }  public static void scheduleWork(String tag) {     PeriodicWorkRequest.Builder photoCheckBuilder =             new PeriodicWorkRequest.Builder(WorkManagerService.class, TIME_INTERVAL_IN_SECONDS,                     TimeUnit.SECONDS);     PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();     WorkManager instance = WorkManager.getInstance();     instance.enqueueUniquePeriodicWork(tag, ExistingPeriodicWorkPolicy.KEEP , photoCheckWork); } 
like image 180
Khemraj Sharma Avatar answered Oct 06 '22 00:10

Khemraj Sharma


from 1.0.0-alpha11 along with many things WorkStatus will not work it's removed and it's a breaking change. Check Release Notes

WorkStatus has been renamed to WorkInfo. All corresponding getStatus method variants have been renamed to the corresponding getWorkInfo variants. This is a breaking change.

after updating to alpha11 the working code is.

private boolean isWorkScheduled(List<WorkInfo> workInfos) {      boolean running = false;      if (workInfos == null || workInfos.size() == 0) return false;      for (WorkInfo workStatus : workInfos) {         running = workStatus.getState() == WorkInfo.State.RUNNING | workStatus.getState() == WorkInfo.State.ENQUEUED;     }      return running; } 
like image 20
Irfan Avatar answered Oct 05 '22 23:10

Irfan