Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Well as WorkManager is newly introduce in Google I/O, I'm trying to use workmanager to perform task periodically,

What I'm doing is, Scheduling the work using PeriodicWorkRequest as following :

Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
PeriodicWorkRequest build = new PeriodicWorkRequest.Builder(SyncJobWorker.class, MY_SCHEDULE_TIME, TimeUnit.MILLISECONDS)
           .addTag(TAG)
           .setConstraints(constraints)
           .build();
WorkManager instance = WorkManager.getInstance();
if (instance != null) {
          instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.REPLACE, build);

Problem I'm having is when i'm requesting PeriodicWorkRequest then also it will start work immediately,

  • Does anybody know how to stop that immediate work execution? while using PeriodicWorkRequest.
  • Also want to know how we can Rechedule the work? What if i want to change the time of already scheduled work ?
  • I'm using : implementation "android.arch.work:work-runtime:1.0.0-alpha04"

    Any help will be appreciated.

    You can achieve this by using flex period in PeriodicWorkRequest.Builder. As example, if you want run your Worker within 15 minutes at the end of repeat interval (let's say 8 hours), code will look like this:

    val periodicRefreshRequest = PeriodicWorkRequest.Builder(
                RefreshWorker::class.java, // Your worker class
                8, // repeating interval
                TimeUnit.HOURS,
                15, // flex interval - worker will run somewhen within this period of time, but at the end of repeating interval
                TimeUnit.MINUTES
    

    Visual ilustration

    you need to add initialDelay to the builder

    fun scheduleRecurringFetchWeatherSyncUsingWorker() {
        val constraints: Constraints = Constraints.Builder().apply {
            setRequiredNetworkType(NetworkType.CONNECTED)
            setRequiresBatteryNotLow(true)
        }.build()
        val request: PeriodicWorkRequest = PeriodicWorkRequest.Builder(
            MySimpleWorker::class.java, 3, TimeUnit.HOURS, 1, TimeUnit.HOURS)
            .setConstraints(constraints)
            .setInitialDelay(2, TimeUnit.HOURS)
            .setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.HOURS)
            .build()
        mWorkManager.enqueueUniquePeriodicWork(
            TAG_WORK_NAME,
            ExistingPeriodicWorkPolicy.KEEP,
            request
    

    Your code always reschedule the work, so you could change the work parameters as you want

    instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.REPLACE, build);
    

    if you want to keep the work with same parameters (even after reboot), without any changes, use:

    instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, build);
    

    in the case it will be scheduled it only if the work is not engueued already.

    For to stop the work task, use

    // cancel the unique work
    instance.cancelUniqueWork(TAG);
    // clear all finished or cancelled tasks from the WorkManager 
    instance.pruneWork();
    

    Btw, I think its not good approach to use same TAG as the unigue work id and as task tag. In case you need unique work - you dont really need the task tag at all. The task tag is for cases then you want to have several tasks

    @UttamPanchasara whats exactly not work? I use it with ExistingPeriodicWorkPolicy.KEEP in OnCreate() for my Application object and with ExistingPeriodicWorkPolicy.REPLACE then I change settings for the task (like scheduling it with different interval). For me it works very well. I also tried instance.wm.cancelUniqueWork(TAG) and for me it works. Btw, I use "android.arch.work:work-runtime:1.0.0-alpha10" – Alex Nov 8, 2018 at 17:18 Policy way that you explained was not working with me,, and I have not tried with latest work manager version – Uttam Panchasara Nov 8, 2018 at 17:31

    You can delay your task using setInitialDelay. This works for both OneTimeWorkRequest and PeriodicWorkRequest .

    val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
       .setInitialDelay(10, TimeUnit.MINUTES)
       .build()

    In case of PeriodicWorkRequest only the first run of your periodic work would be delayed.

    We have used setInitialDelay to ensure the notification is triggered on the day of the event rather than immediately. This delay is calculated by a separate method which returns the amount of milliseconds between now and when the notification should trigger (at noon on the date of the event). Please note that this delay is not always accurate! Due to how modern Android works, your work can be delayed by a number of factors, so be aware of this for very time sensitive purposes.

    All the info is in this post. https://medium.com/@eydryan/scheduling-notifications-on-android-with-workmanager-6d84b7f64613

    setInitialDelay will only work with oneTimeRequest I'm scheduling with periodic work request. – Uttam Panchasara Jul 18, 2018 at 16:17

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid …

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.