lchristmann
lchristmann

Reputation: 625

Why does my WorkManager Work never have Internet connection when running in the background?

In my Android application "Tracker" I am using WorkManager to track the user's location and upload it to an API.

In the foreground everything works perfectly, i.e.

  1. Getting the location and storing it in a local database
  2. Uploading the data from the database to a remote API

But in the background the second step breaks (i.e. when I enqueue the Work and navigate to the homescreen, but not closing the app), because Internet is always missing.

Somehow there's never any network available, although I've defined the permissions in my AndroidManifest.xml:

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

I schedule the Work like this in my MainActivity.kt - the 20s delay allows me to go somewhere else in the foreground before the Work runs:

val oneTimeRequest = OneTimeWorkRequestBuilder<LocationWorker>()
   .setInitialDelay(20, TimeUnit.SECONDS)
   .build()
WorkManager.getInstance(context)
   .enqueue(oneTimeRequest)

And the LocationWorker.kt looks as below. The private helper function isNetworkAvailable() proves the point that always when I have the app open in the background, but not on-screen, there's no Internet! Why?

Location tracking and database operations both work smoothly in the background - but not Internet...

class LocationWorker(
    context: Context,
    workerParams: WorkerParameters
): CoroutineWorker(context, workerParams) {

   override suspend fun doWork(): Result {
   
      // ... (1. Getting the location and storing it in a local database)

      if (isNetworkAvailable(applicationContext)) {
         // Always get here when the app is visible on-screen
         Log.d("LocationWorker", "Uploading location.")
         // ... (2. Uploading the data from the database to a remote API)
      } else {
         // Always get here when not having the app on-screen
         Log.d("LocationWorker", "Network not available.")
      }
   }

   private fun isNetworkAvailable(context: Context): Boolean {
      val connectivityManager = context.getSystemService(ConnectivityManager::class.java)
      val network = connectivityManager.activeNetwork ?: return false
      val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
      return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
   }

I ensured that the device itself has WiFi enabled, the app is not stripped of permissions when unused and all permissions are allowed.

Note that I have minSdk = 29 (Android 10) specified and use the Pixel 7 API 35 Emulator for development.

Upvotes: 0

Views: 32

Answers (0)

Related Questions