如何确保在Android N及以上版本上设备重启时调用PeriodicWorkRequests

4

我最近尝试使用WorkManagerPeriodicWorkRequest作为在后台周期性获取用户位置更新的一种可靠方法。这个库符合我的要求,特别是以下细节引起了我的注意:

即使应用程序或设备重新启动,也保证任务执行

在实施和测试之后,我尝试重新启动我的设备并注意到日志消息和应用通知从未显示出来。

自然而然地,我进行了一些调查,并偶然发现了这个:Android Oreo中的设备重启后PeriodicWorkRequest无法正常工作问题

因此,我尝试使用BOOT_COMPLETED广播接收器在设备重启时触发WorkRequest,但它没有起作用。我在SO上检查了许多BOOT_COMPLETED接收器的问题,但除了这里的一个解决方案外:Android设备重启后广播接收器不起作用,但那需要使用户选择您的应用作为AccessibilityService,我认为这会影响用户体验。

经过一些调查,我发现WorkManager在内部使用BOOT_COMPLETED广播接收器。到目前为止,我已经在Android Nougat和Oreo设备上进行了测试,因此我在运行API 16的三星和运行API 22的HTC上测试了广播接收器。接收器可以正常工作,我将其删除并同时测试了重启时的WorkRequests;它们也可以正常工作!

以下是我如何实现我的PeriodicWorkRequest

PeriodicWorkRequest request =
                new PeriodicWorkRequest.Builder(LocationListenerWorker.class,
                        12, HOURS)
                        .build();

        mWorkManager.enqueueUniquePeriodicWork(Constants.LOCATION_TASK_ID,
                ExistingPeriodicWorkPolicy.REPLACE, request);

希望能得到关于如何确保在运行API 24+的设备上,请求在设备重新启动时也会被调用的任何帮助。


3
更新:我发现这不是API问题,而是与设备制造商有关。 Tecno和Infinix的HiOS和XOS Android版本限制了访问监听BOOT_COMPLETED广播的功能,这也影响了WorkManager。 - Mofe Ejegi
你找到解决方案了吗?我也在想同样的问题。 - IgorGanapolsky
尝试从设置中手动启用“自动启动”,如果可以,请实现此库https://github.com/judemanutd/AutoStarter。 - Rajesh Koshti
1个回答

0
假设您已经定义了一个RebootWorker类,它扩展了Worker并在设备重新启动后执行某些特定的工作。第一种方法:
public class RebootWorker extends Worker {
...............................
}

在这种情况下,在清单文件中定义该工作者。
<service
    android:name=".RebootWorker"
    android:process=":worker"/> 

这将有助于让WorkManager在设备重启后运行您的工作服务。因为由于设备重启,您的应用程序会从任务管理器中清除。

第二种方法:您还可以使用BroadcastReceiver来监听启动完成的操作

public class MyReceiver extends BroadcastReceiver {
    WorkManager mWorkManager;
    PeriodicWorkRequest rebootRequest;

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(MainActivity.TAG, "intent.getAction(): "+intent.getAction());

        //Reboot worker
        mWorkManager = WorkManager.getInstance(context);
        rebootRequest = new PeriodicWorkRequest.Builder(RebootWorker.class,
                MainActivity.REPEAT_INTERVAL, MainActivity.TIME).build();

        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
           //do your work and enqueue it 
            mWorkManager.enqueue(rebootRequest);
}
}
}

1
你为什么把worker放在清单中作为服务?你在哪里读到的? - Philip
@Philip 在第一种方法中,我将RebootWorker作为服务放在清单中,以便在设备重新启动时它会再次启动。 - SAURABH_12
1
一个 Worker 不是一个 Service。因此,这个 AndroidManifest 声明不准确。 - IgorGanapolsky

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