Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WorkManager get time of next scheduled work by tag

I am using WorkManager to schedule both periodic and one-time work, and I am tagging all of the work with the same tag so that I can identify it later:

workRequestBuilder.addTag("mywork");

With various work items enqueued, at various times in the future, I would like a way of querying the work queue to determine when the next work is scheduled to run for this particular tag ("mywork"). Yes, I know that it will not be exact and will be subject to Doze etc, but it would still be useful to know when -- in the absence of other factors -- the work is likely to run.

I know how to query the work queue and pick out enqueued work items as follows, but I'm just not sure how to tell what time each work item is scheduled to run:

WorkManager workManager = WorkManager.getInstance();
ListenableFuture<List<WorkInfo>> workInfos = workManager.getWorkInfosByTag("mywork");

try {
    List<WorkInfo> workInfoList = workInfos.get();
    for (WorkInfo workInfo : workInfoList) {
        WorkInfo.State state = workInfo.getState();
        if (state == WorkInfo.State.ENQUEUED) {
            UUID workerId = workInfo.getId();
            Log.d(TAG, "found enqueued work with id " + workerId);
            // BUT HOW DO I TELL WHAT TIME THIS WORK IS SCHEDULED TO RUN?
        }
    }
} catch (ExecutionException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}
like image 610
drmrbrewer Avatar asked Jan 20 '19 20:01

drmrbrewer


1 Answers

I found only 2 ways to "work around" this:

Prerequistions

Don't use periodic work! Always schedule the next periodic work manually with a OneTimeWorkRequest instead.

Workaround 1:

  • when creating the WorkRequest you will call setInitialDelay. After enqueing the request, you can get it's id => save this id in a database with the execution time (and maybe policy infos and whatever you want), then you can always query the database and get the next execution time
  • when a WorkRequest is executed, remove it from the database and then schedule the next "periodic" task manually as a OneTimeWorkRequest

Workaround 2:

  • add 2 custom tag like "HasRunAt" and "RunAt:TIME_TO_RUN" to all your WorkRequests
  • then get all WorkInfos like WorkManager.getInstance().getWorkInfosByTag("HasRunAt") and check their tags and parse the one that starts with "RanAt:"...

Conclusion

No solution is beautiful and I would like to have the ability of following as well:

  • get the exectuion time, policy, ... from a WorkInfo
  • get the InputData from the WorkInfo - then you could put all the extra info you want to access to this data and get it from there instead...
like image 174
prom85 Avatar answered Oct 18 '22 10:10

prom85