Android WorkManager - как отложить задачу?

Я создаю функционал, который позволит продавцам устанавливать график своего бизнеса. Такая функция автоматически изменяет переменную open на true и false в соответствии с временем, установленным продавцом для каждого дня недели. Следовательно, всего будет 14 возможных различных моментов времени.

Я пытаюсь создать повторяющуюся фоновую задачу, которая могла бы выполнить такую ​​задачу, с помощью WorkManager, новой библиотеки компонентов архитектуры Android.

val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
                .setInputData(Data.Builder().putBoolean("isStart", true).build())
                .setScheduleRequestedAt(diff_time, TimeUnit.MILLISECONDS)
                .addTag(weekdays[index])
                .build()

Однако это дает мне следующую ошибку APILibraryException:

Builder.setScheduleRequestedAt можно вызывать только из той же группы библиотек.

Мои вопросы:

1) Является ли это setScheduleRequestedAt правильным методом вызова, если я хочу отложить планирование на diff_time?

2) Если да, то как я могу решить эту проблему?

PS: diff_time - это разница в миллисекундах между соответствующими часами каждого дня, установленная пользователем. Пример: понедельник-пятница = 08:00, сб-вс = 10:00.


person rgoncalv    schedule 29.10.2018    source источник
comment
Я не могу найти этот метод в developer.android.com/reference/ Javadoc androidx / work /   -  person Marko Topolnik    schedule 29.10.2018
comment
Да: / Я тоже не нашел, но этот метод существует при написании кода. Есть ли какой-нибудь другой метод, который может задержать планирование?   -  person rgoncalv    schedule 29.10.2018
comment
Вероятно, нет способа запланировать повторное задание с начальной задержкой. В JobScheduler такой функции нет, а WorkManager находится на уровне выше нее.   -  person Marko Topolnik    schedule 29.10.2018
comment
Но такая функциональность есть в AlarmManager, и WorkManager - это тоже слой над ней, верно?   -  person rgoncalv    schedule 29.10.2018


Ответы (3)


ОБНОВЛЕНИЕ

Начиная с WorkManager v2.1-alpha02 теперь возможно добавить начальную задержку к PeriodicWorkRequest. Теперь ваш звонок стал просто:

val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
                .setInputData(Data.Builder().putBoolean("isStart", true).build())
                .setInitialDelay(diff_time, TimeUnit.MILLISECONDS)
                .addTag(weekdays[index])
                .build()

Примечание, поскольку setInitialDelay был введен в родительский класс _ 4_, это привело к бинарному изменению, перемещающемуся с v2.0 на v2.1 для метода OneTimeWorkRequest#setInitialDelay(). Это означает, что для использования новой библиотеки вам необходимо перекомпилировать проект при обновлении с v2.0.

Соответствует исходному ответу

Невозможно отложить первый запуск периодической задачи с помощью WorkManager.

Лучше всего использовать OneTimeWorker с желаемой задержкой, и оттуда вы можете поставить в очередь своего периодического работника с желаемым периодом.

В трекере проблем WorkManager есть запрос функции с объяснением этого обходного пути, который можно использовать в качестве справки.

Примечание. из-за того, как работает минимальный интервал, вы не можете создать периодический рабочий запрос, который выполняется в повторяющееся время, например каждый день в 4:00 утра. Вы можете указать 24-часовой интервал повтора, но при этом рабочий может выполняться в 4:05 утра в первый день, в 6:00 во второй, в 6:10 в третий день и так далее. Если вам нужно запускать воркер в одно и то же время каждый день, лучше всего использовать OneTimeWorkRequest с начальной задержкой:

OneTimeWorkRequest save = new OneTimeWorkRequest
            .Builder(SaveImageToFileWorker.class)
            .setConstraints(constraints)
            .setInitialDelay(24, TimeUnit.HOURS)
            .addTag(TAG_OUTPUT)
            .build();

Когда рабочий будет завершен, вы можете перепланировать его с помощью Delay, чтобы он запускался в правильное время (точное время, когда рабочий будет выполнен, зависит от ограничений, которые вы используете при создании запрос на работу).

person pfmaggi    schedule 30.10.2018

Вам необходимо обновить версию библиотеки диспетчера работ до 2.1.0- alpha03. В версии WorkManager есть возможность добавлять начальную задержку в задачу.

Затем вам нужно использовать метод setInitialDelay (). Ниже приводится реализация того же метода для достижения определенного времени работы триггера:

long initialDelayInSeconds = (futureSpecificTime - System.currentTimeInMills()) / 1000;

PeriodicWorkRequest workRequest =
                new PeriodicWorkRequest.Builder(WorkerClass.class, interval, TimeUnit.SECONDS)
                        .setConstraints(workRequestConstraints)
                        .setInputData(inputData)
                        .addTag(TAG_TASK)
                        .setInitialDelay(initialDelayInSeconds, TimeUnit.SECONDS)
                        .build();
person Manmohan Soni    schedule 06.06.2019

В новой версии Диспетчера работ (Версия 2.1.0-alpha02 от 16 мая 2019 г.) PeriodicWorkRequests теперь поддерживает начальные задержки. Вы можете использовать метод setInitialDelay в PeriodicWorkRequest.Builder, чтобы установить начальную задержку.

PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
        WorkerReminderPeriodic.class,
        24,
        TimeUnit.HOURS,
        PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,
        TimeUnit.MILLISECONDS)
    .setInitialDelay(1, TimeUnit.HOURS)
    .addTag("send_reminder_periodic")
    .build();


WorkManager.getInstance()
        .enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest);
person Anjal Saneen    schedule 22.05.2019