首页 > 解决方案 > 如何仅在使用 WorkManager 的蜂窝网络上运行作业?

问题描述

我正在开发一个应用程序,它必须在 WiFi 连接丢失时运行作业。我可以使用 WorkManager 轻松检测设备何时获得 WiFi 连接,但我还没有找到一种方法将 Worker 设置为仅在蜂窝数据上运行,我会在检测到用户已连接到 WiFi 网络后立即设置。

我过去的做法是使用 BroadcastReceivers,它可以让我知道用户何时连接或断开 WiFi 网络。

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<receiver android:name=".NetworkChangeReceiver">
   <intent-filter>
      <action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE"/>
   </intent-filter>
</receiver>

不幸的是,在 API 28 中,SUPPLICANT_CONNECTION_CHANGE_ACTION 已被弃用。

不过值得庆幸的是,在 API 28 中,我现在可以使用 JobScheduler 来实现类似的效果,像这样设置作业:

val jobBuilder = JobInfo.Builder(jobId, ComponentName(context, NetworkService::class.java))
val requiredNetwork = NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build()
jobBuilder.setRequiredNetwork(requiredNetwork)

我知道我可以结合这两种解决方案并根据设备 API 使用其中一种,但我想避免它。我查看了 WorkManager,但没有找到仅在蜂窝数据上运行 Worker 的方法。我是否遗漏了什么,或者 WorkManagers 目前无法做到这一点?

标签: androidbroadcastreceiverandroid-workmanagerandroid-jobscheduler

解决方案


更新如果您可以假设蜂窝网络始终按流量计费,而 WiFi 始终不按流量计费,您可以使用这些 NetworkTypes 作为约束。有关更多详细信息,请参阅评论,因为似乎并非总是如此。

原始答案

Network.METERED您可以在有 WIFI 连接时运行的 Work 中创建一个带有约束的新WorkRequest。

当设备切换到蜂窝(计量)连接时,将运行这项新工作:

// Create a Constraints object that defines when the task should run
val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.METERED)
        .build()

WorkManager 指南涵盖了带约束的 WorkRequest


推荐阅读