Android 使用WorkManager在特定时间安排工作
WorkManager是一个库,用于将保证在满足约束后执行的工作排队Android 使用WorkManager在特定时间安排工作,android,android-workmanager,Android,Android Workmanager,WorkManager是一个库,用于将保证在满足约束后执行的工作排队 因此,在浏览了这个类之后,我还没有找到任何函数来为工作添加时间限制。例如,我想在早上8:00开始一项工作(该工作可以是两种类型中的任何一种或两种类型)。如何使用WorkManager添加约束以安排此工作。很遗憾,您目前无法在特定时间安排工作。如果您有时间关键型实现,那么您应该使用AlarmManager通过使用或将在打瞌睡时可能触发的警报设置为 您可以使用WorkManager按如下方式安排一项具有一次性初始延迟的工作或定期执
因此,在浏览了这个类之后,我还没有找到任何函数来为工作添加时间限制。例如,我想在早上8:00开始一项工作(该工作可以是两种类型中的任何一种或两种类型)。如何使用WorkManager添加约束以安排此工作。很遗憾,您目前无法在特定时间安排工作。如果您有时间关键型实现,那么您应该使用AlarmManager通过使用或将在打瞌睡时可能触发的警报设置为 您可以使用
WorkManager
按如下方式安排一项具有一次性初始延迟的工作或定期执行该工作:
创建工人类:
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 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);
然后安排OneTimeWorkRequest
如下:
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 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);
然后创建使用这些约束的OneTimeWorkRequest
OneTimeWorkRequest mywork=
new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(myConstraints)
.build();
WorkManager.getInstance().enqueue(mywork);
PeriodicWorkRequest可以按如下方式创建:
这会创建一个PeriodicWorkRequest,每12小时定期运行一次。到目前为止,使用
PeriodicWorkRequest
无法获得准确的时间难看的解决方法是使用
OneTimeWorkRequest
,当它触发时,用新的计算周期设置另一个OneTimeWorkRequest
,以此类推。您可以使用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
}
}
}
然后在应用程序类中启动
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'
}
如果要将初始延迟设置为周期性工作请求,我在这里介绍了解决方案:
现在所有答案都已过时,请升级到WorkManager 2.1.0-alpha02(或更高版本) setInitialDelay()方法仅用于OneTimeWorkRequest,但现在它们还支持PeriodicWorkRequest
implementation "androidx.work:work-runtime:2.1.0-alpha02"
PeriodicWorkRequests现在支持初始延迟。你可以使用 在PeriodicWorkRequest.Builder上设置InitialDelay方法以设置 初始延迟 快速示例:
new PeriodicWorkRequest.Builder(MyWorker.class, MY_REPEATS, TimeUnit.HOURS)
.setInitialDelay(THE_DELAY,TimeUnit.SECONDS);
PeriodicWorkRequests现在支持版本2.1.0-alpha02的初始延迟。您可以对PeriodicWorkRequest.Builder使用setInitialDelay方法来设置初始延迟 每天上午8:00的时间表示例。这里我用的是时间运算
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);
final int SELF\u rements\u HOUR=8;
if(DateTime.now().getHourOfDay()
我可能会有点晚,但无论如何,我这样做是为了在给定时间安排工作请求(可选的短延迟)。您只需从计时员那里获取时间:
public static void scheduleWork(int hour, int minute) {
Calendar calendar = Calendar.getInstance();
long nowMillis = calendar.getTimeInMillis();
if(calendar.get(Calendar.HOUR_OF_DAY) > hour ||
(calendar.get(Calendar.HOUR_OF_DAY) == hour && calendar.get(Calendar.MINUTE)+1 >= minute)) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
calendar.set(Calendar.HOUR_OF_DAY,hour);
calendar.set(Calendar.MINUTE,minute);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND,0);
long diff = calendar.getTimeInMillis() - nowMillis;
WorkManager mWorkManager = WorkManager.getInstance();
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
mWorkManager.cancelAllWorkByTag(WORK_TAG);
OneTimeWorkRequest mRequest = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setConstraints(constraints)
.setInitialDelay(diff,TimeUnit.MILLISECONDS)
.addTag(WORK_TAG)
.build();
mWorkManager.enqueue(mRequest);
}
我试过一次工作请求,但它是脆弱的(只在有时工作),所以我们不应该依赖它。AlarmManager是一个更好的选择 ?我认为,这是解决问题的好办法。为此,我必须计算当前时间和我希望开始工作的时间之间的时间差。但是,我可以明确地设置开始时间吗?计算
timeInFutureInSeconds-timenowunseconds
有什么问题吗?@pskink但是,正如问题所问,我们如何指定工作必须每天早上8点完成。?初始延迟规定为“初始”延迟。workmanager如何知道下一次我们需要运行它。由于该任务是周期性任务,workmanager将在第一次触发该任务的同时触发该任务。问题是,它在周期性工作中不起作用。@Gatek,它的整体。谷歌IO中提到了它。如果您想这样做,那么安排OneTimeWorkRequest,它将在2小时后触发,PeriodicWorkRequest将在下午2点执行。有两种方法setInitialDelay,一种方法期望将持续时间作为参数,仅在API 26中(因为它来自Java 8),另一种方法需要持续时间和时间单位,在每个平台上都可用。如何接受此答案?问题是我们必须在上午8点开始工作。没有提到这一点?这是因为你不能在特定的时间安排与WorkManager的工作哇。。。这是相当令人厌恶的。X.XI不相信有一个理由从Evernote Android工作转移到这里。请在这里回答我的问题:@ KoooKek,事实上,它是由WorkMeals@ MHHAMM6的开发人员建议的,有一些例子吗?我相信在将来,执行时间的偏移将非常大…但是用REPLACE
对我来说似乎没问题,它只会在24小时周期结束时第一次解雇定期工。有什么方法可以让它在创建后立即工作吗?(例如,应在17:50运行,在17:40排队,并在10分钟后第一次运行)此外,如果用户更改其时间设置,工作人员将保持不变(例如,工作人员应在每天上午8:00运行。如果用户设置另一个时区,例如+3小时以上,它将不会在上午11:00运行)我尝试过,但经常无法按预期运行,因此,最好使用AlarmManager确定,如果时间是准确的,那么现在就有一天Alarm Manager没有被解雇,出于后台目的,这个答案是完美的,