WorkManagerは、制約が満たされた後に実行が保証される作業をキューに入れるために使用されるライブラリです。
したがって、 Constraints クラスを実行した後、作業に時間制約を追加する関数が見つかりませんでした。たとえば、午前8時に実行する作業を開始したい(作業は2つのタイプ OneTimeWorkRequest または PeriodicWorkRequest のいずれかになります)。 WorkManagerでこの作業をスケジュールするための制約を追加するにはどうすればよいですか。
残念ながら、現時点では特定の時間に作業をスケジュールすることはできません。タイムクリティカルな実装がある場合は、AlarmManagerを使用して、Dozeのときに setAndAllowWhileIdle() または setExactAndAllowWhileIdle() を使用して起動できるアラームを設定する必要があります。
次のようにWorkManager
を使用して、1回限りの初期遅延で作業をスケジュールしたり、定期的に実行したりできます。
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 periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 12, TimeUnit.HOURS)
.build();
WorkManager.getInstance().enqueue(periodicWork);
これにより、PeriodicWorkRequestが作成され、12時間ごとに定期的に実行されます。
これまでのところ、PeriodicWorkRequest
を使用して正確な時間を達成することはできません。
い回避策は、OneTimeWorkRequest
を使用し、それが起動したときに、新しい計算された期間で別のOneTimeWorkRequest
を設定することです。
PeriodicWorkRequestsは、バージョン2.1.0-alpha02からの初期遅延をサポートするようになりました。 PeriodicWorkRequest.BuilderでsetInitialDelayメソッドを使用して、初期遅延を設定できます。 ここにリンク
毎日午前8時にスケジュールの例。ここでは、時間操作に joda time library を使用しています。
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);
EvernoteからAndroidJobを使用できます
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
}
}
}
その後、Applicationクラスで開始します
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'
}
初期遅延をPeriodicWorkRequestに設定する場合、ここで解決策を示しました。
すべての回答は廃止されました。WorkManager2.1.0-alpha02(またはそれ以降)setInitialDelay()メソッドにアップグレードすると、OneTimeWorkRequestのみで機能しますが、PeriodicWorkRequestもサポートするようになりました。
implementation "androidx.work:work-runtime:2.1.0-alpha02"
PeriodicWorkRequestsが初期遅延をサポートするようになりました。 PeriodicWorkRequest.BuilderでsetInitialDelayメソッドを使用して、初期遅延を設定できます。
簡単な例:
new PeriodicWorkRequest.Builder(MyWorker.class,
MY_REPEATS, TimeUnit.HOURS).setInitialDelay(THE_DELAY,TimeUnit.SECONDS);