Запланируйте работу в определенное время с помощью WorkManager
WorkManager - это библиотека, используемая для выполнения задания, которое гарантировано выполняется после того, как будут выполнены его ограничения.
Следовательно, после прохождения класса Constraints я не нашел никакой функции, чтобы добавить ограничение времени на работу. Например, я хочу начать работу в 8:00 утра (работа может быть любой из двух типов OneTimeWorkRequest или PeriodicWorkRequest) по утрам. Как я могу добавить ограничение для планирования этой работы с WorkManager.
Ответы
Ответ 1
К сожалению, вы не можете запланировать работу в определенное время на данный момент. Если у вас есть реализация, критичная ко времени, вы должны использовать AlarmManager для установки будильника, который может срабатывать в режиме Doze to, с помощью setAndAllowWhileIdle() или setExactAndAllowWhileIdle().
Вы можете запланировать работу с единовременной начальной задержкой или выполнять ее периодически, используя WorkManager
следующим образом:
Создать класс Worker:
public class MyWorker extends Worker {
@Override
public Worker.WorkerResult doWork() {
// Do the work here
// Indicate success or failure with your return value:
return WorkerResult.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}
Затем запланируйте OneTimeWorkRequest
следующим образом:
OneTimeWorkRequest mywork=
new OneTimeWorkRequest.Builder(MyWorker.class)
.setInitialDelay(<duration>, <TimeUnit>)// Use this when you want to add initial delay or schedule initial work to 'OneTimeWorkRequest' e.g. setInitialDelay(2, TimeUnit.HOURS)
.build();
WorkManager.getInstance().enqueue(mywork);
Вы можете настроить дополнительные ограничения следующим образом:
// Create a Constraints that defines when the task should run
Constraints myConstraints = new Constraints.Builder()
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
// Many other constraints are available, see the
// Constraints.Builder reference
.build();
Затем создайте OneTimeWorkRequest, который использует эти ограничения
OneTimeWorkRequest mywork=
new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(myConstraints)
.build();
WorkManager.getInstance().enqueue(mywork);
PeriodicWorkRequest может быть создан следующим образом:
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 12, TimeUnit.HOURS)
.build();
WorkManager.getInstance().enqueue(periodicWork);
Это создает PeriodicWorkRequest для периодического запуска каждые 12 часов.
Ответ 2
Пока что невозможно достичь точного времени, используя PeriodicWorkRequest
.
OneTimeWorkRequest
будет использовать OneTimeWorkRequest
и, когда он запускается, установить другой OneTimeWorkRequest
с новым рассчитанным периодом, и так далее.
Ответ 3
Вы можете использовать AndroidJob от evernote
class NotificationJob : DailyJob() {
override fun onRunDailyJob(params: Params): DailyJobResult {
//your job
return DailyJobResult.SUCCESS
}
companion object {
val TAG = "NotificationJob"
fun scheduleJob() {
//scheduled between 9-10 am
DailyJob.schedule(JobRequest.Builder(TAG),
TimeUnit.HOURS.toMillis(9),TimeUnit.HOURS.toMillis(10 ))
}
}
}
и создатель уведомлений
class NotificationJobCreator : JobCreator {
override fun create(tag: String): Job? {
return when (tag) {
NotificationJob.TAG ->
NotificationJob()
else ->
null
}
}
}
затем начать в вашем классе приложения
JobManager.create(this).addJobCreator(NotificationJobCreator())
Зависимость Gradle
dependencies {
implementation 'com.evernote:android-job:1.2.6'
// or this with workmnager
implementation 'com.evernote:android-job:1.3.0-alpha08'
}
Ответ 4
Если вы хотите установить начальную задержку для PeriodicWorkRequest, я представил решение здесь:
Установите начальную задержку для диспетчера периодической работы в Android
Ответ 5
Все ответы теперь устарели, обновите до метода WorkManager 2.1.0-alpha02 (или выше) метод setInitialDelay(), используемый для работы только для OneTimeWorkRequest, но теперь они также поддерживают PeriodicWorkRequest.
implementation "androidx.work:work-runtime:2.1.0-alpha02"
PeriodicWorkRequests теперь поддерживает начальные задержки. Вы можете использовать метод setInitialDelay в PeriodicWorkRequest.Builder, чтобы установить начальную задержку
быстрый пример:
new PeriodicWorkRequest.Builder(MyWorker.class,
MY_REPEATS, TimeUnit.HOURS).setInitialDelay(THE_DELAY,TimeUnit.SECONDS);
Ответ 6
PeriodicWorkRequests теперь поддерживает начальные задержки с версии 2.1.0-alpha02. Вы можете использовать метод setInitialDelay в PeriodicWorkRequest.Builder, чтобы установить начальную задержку. Ссылка здесь
Пример расписания на каждый день в 8:00. здесь я использую библиотеку времени joda для операций времени.
final int SELF_REMINDER_HOUR = 8;
if (DateTime.now().getHourOfDay() < SELF_REMINDER_HOUR) {
delay = new Duration(DateTime.now() , DateTime.now().withTimeAtStartOfDay().plusHours(SELF_REMINDER_HOUR)).getStandardMinutes();
} else {
delay = new Duration(DateTime.now() , DateTime.now().withTimeAtStartOfDay().plusDays(1).plusHours(SELF_REMINDER_HOUR)).getStandardMinutes();
}
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
WorkerReminderPeriodic.class,
24,
TimeUnit.HOURS,
PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,
TimeUnit.MILLISECONDS)
.setInitialDelay(delay, TimeUnit.MINUTES)
.addTag("send_reminder_periodic")
.build();
WorkManager.getInstance()
.enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest);