I am creating a backup app which backs up some files at night. Because it needs to be every night around the same time I'm using a OneTimeWorkRequest which will be scheduled again after the last time has run. So this is the code I am using:
private fun scheduleNextSyncWorker(context: Context) {
val nextScheduleDelay = 60000L
val test = OneTimeWorkRequestBuilder<TestWorker>()
.setInitialDelay(nextScheduleDelay, TimeUnit.MILLISECONDS)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
)
.addTag("test")
.build()
WorkManager.getInstance(context)
.enqueueUniqueWork("test", ExistingWorkPolicy.REPLACE, test)
}
class TestWorker(appContext: Context, workerParameters: WorkerParameters) : CoroutineWorker(appContext, workerParameters) {
override suspend fun doWork(): Result {
try {
withContext(Dispatchers.IO) {
val connectivityManager = applicationContext.connectivityManager()
var waitedMillis = 0L
var waitedSince = System.currentTimeMillis()
// Added this to check if it is connected and usually this is false
while(connectivityManager.activeNetworkInfo?.isConnected != true && waitedMillis < 10000) {
Log.d("TEST", "connected: ${connectivityManager.activeNetworkInfo?.isConnected}")
waitedMillis = System.currentTimeMillis() - waitedSince
delay(1000)
}
// Api calls here which mostly fail because no internet connection
}
return Result.success()
} catch (t: Throwable) {
return Result.failure()
} finally {
GlobalScope.launch {
// Probably not the best way, but the worker needs to pass back that we succeeded or failed before we will schedule the next
delay(1000)
scheduleNextSyncWorker(applicationContext)
}
}
}
}
This code will all run fine while the app is in the foreground. However as soon as I move the app to the background and lock the device most api calls fail with java.net.UnknownHostException: Unable to resolve host "graph.microsoft.com": No address associated with hostname
.
Like you can see in the code I have some extra code to check if we are currently connected which when device is locked is mostly false. Sometimes after a few seconds we regain internet access, but sometimes not.
I thought the WorkManager was supposed to call doWork only if the constraints are met. But since I'm not having an active connection I'm not sure how I should continue. It seems trivial to add a full network check inside the worker while it's suppose to check it itself.
Any thoughts?
I figured it out after a lot of headaches and hours of work. It is a bug in the new 2.10.0 version. This is the first time I used WorkManager, so didn't know it had to do with the new version. Just revert back to 2.9.1 and it will work again.
I created an issue on IssueTracker: https://issuetracker.google.com/issues/387656869