如何在特定时间排队WorkManager OneTimeWorkRequest

4

我有一个场景,需要在特定时间使用 WorkManager 给用户发送通知。

如何在特定时间安排 Work,并且即使用户强制停止应用程序或应用程序没有运行,它也应该出现。

我的当前代码如下:

Data d = new Data.Builder().putInt(IntentConstants.SCHEDULE_ID, scheduleData.getScheduleID()).build();
OneTimeWorkRequest compressionWork =
    new OneTimeWorkRequest.Builder(ScheduleWorker.class)
        .setInputData(d)
        .build();
WorkManager.getInstance().enqueue(compressionWork);

1
你不能在精确的时间点上启动一个 WorkManager 工作。但是,你可以通过使用高优先级的 FCM 来确保你被列入白名单,并将工作排队(和运行)。另一种选择是使用 AlarmManagersetExactAndAllowWhileIdle() 方法。参考这里(Doze 和 App Standby 部分)- https://google-developer-training.gitbooks.io/android-developer-fundamentals-course-concepts/content/en/Unit%203/82c_scheduling_alarms_md.html#scheduling - HedeH
3个回答

9

我认为我已经找到了一个简单且有效的解决方案。它百分之百有效。

我们需要获取当前时间的毫秒数并将所需的特定时间转换成毫秒,然后计算特定时间减去当前时间。

以下是我的解决方案(可行的代码如下):

Data d = new Data.Builder()
             .putInt(IntentConstants.SCHEDULE_ID, scheduleData.getScheduleID())
             .build();

long currentTime= System.currentTimeMillis();
long specificTimeToTrigger = c.getTimeInMillis();
long delayToPass = specificTimeToTrigger - currentTime;

OneTimeWorkRequest compressionWork =
                        new OneTimeWorkRequest.Builder(ScheduleWorker.class)
                                .setInputData(d)
                                .setInitialDelay(delayToPass, TimeUnit.MILLISECONDS)
                                .build();

WorkManager.getInstance().enqueue(compressionWork);

主要逻辑在delayToPass = 当前时间(毫秒) - 特定触发时间(毫秒)


0
long currentTime= System.currentTimeMillis();
long specificTimeToTrigger = c.getTimeInMillis();
long delayToPass = specificTimeToTrigger - currentTime;

OneTimeWorkRequest compressionWork =
                        new OneTimeWorkRequest.Builder(ScheduleWorker.class)
                                .setInitialDelay(delayToPass, TimeUnit.MILLISECONDS)
                                .build();

WorkManager.getInstance().enqueue(compressionWork);

当所选时间 > 当前时间时,它会在所选时间正确触发。 如果所选时间 < 当前时间,则会立即触发。

为了克服立即触发的问题,您可以使用以下条件,如果所选时间小于当前时间,则触发下一天。

if ((specificTimeToTrigger - currentTime) < 0) {
    delayToPass = (86400000)-(currentTime - specificTimeToTrigger);
    //24hr-(currentTime - specificTimeToTrigger)
} else {
    delayToPass = specificTimeToTrigger - currentTime;
}

-1

被接受的答案准确而且简明扼要,但我认为有一个小细节是误导人的
delayToPass = currentTime (in Millis) - specificTimeToTrigger (in Millis) 在我看来这样行不通,应该像这样:
delayToPass = specificTimeToTrigger (in Millis)-currentTime (in Millis)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接