WorkManager.getInstance().cancelAllWorkByTag() not stopping the periodic job
I believe the problem you are having here is answered in this duplicate question.
In summary, if you have a pending worker which hasn't started yet, the worker will be cancelled and will not run. However if the worker is already running, cancelling work does not terminate the worker in a hard fashion - it simply sets the state flag of the worker to CANCELLED
, as explained in the docs. It is up to you to handle the cancellation inside your doWork
and terminate the worker.
One way to do this is to put a few checks in your doWork
method to check if the worker has been cancelled, by calling isStopped()
. If isStopped
is true, return from the method with a Result
instead of continuing with the rest of the work.
While creating PeriodicWorkRequest i had added addTag() and to cancel task used same tag name, using this it cancel pending work. So my code is like:
PeriodicWorkRequest.Builder wifiWorkBuilder =
new PeriodicWorkRequest.Builder(FileUpload.class, 15,
TimeUnit.MINUTES)
.addTag("WIFIJOB1")
.setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.METERED).build());
wifiWork = wifiWorkBuilder.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("wifiJob", ExistingPeriodicWorkPolicy.REPLACE, wifiWork);
To stop job I am using:
WorkManager.getInstance().cancelAllWorkByTag("WIFIJOB1");
I've been checking the official Android docs: https://developer.android.com/reference/androidx/work/WorkManager
There are two types of work supported by WorkManager: OneTimeWorkRequest and PeriodicWorkRequest.
You can enqueue requests using WorkManager as follows:
WorkManager workManager = WorkManager.getInstance();
workManager.enqueue(new OneTimeWorkRequest.Builder(FooWorker.class).build());
A WorkRequest has an associated id that can be used for lookups and observation as follows:
WorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class).build();
workManager.enqueue(request);
LiveData<WorkStatus> status = workManager.getStatusById(request.getId());
status.observe(...);
You can also use the id for cancellation:
WorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class).build();
workManager.enqueue(request);
workManager.cancelWorkById(request.getId());
And here you can see a different ways to cancel a enqueued work:
Maybe you also can try to cancel a enqueued or blocked job using the State of the job:
WorkStatus workStatus = WorkManager.getInstance().getStatusById(wifiWork.getId()).getValue();
if(workStatus.getState() == State.ENQUEUED || workStatus.getState() == State.BLOCKED){
WorkManager.getInstance().cancelWorkById(wifiWork.getId());
}
I hope it helps you.