NamNH
NamNH

Reputation: 1805

Retrieve background location using WorkManager always return same lastknown location

My app works fine if using foreground service to get user location, however in background I just need location for each 15 minutes, also Google requires new Policy for getting background location so, foreground service is over my expectation.

I am trying to get location from background using WorkManager, it can run normally every (around) 15 minutes. My location is requested, however it always returns the previous address, even 1, 2... hours are passed.

Here is my code:


class LocationWorker(private val context: Context, params: WorkerParameters) :
        CoroutineWorker(context, params) {
    
   private var fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
  
   override suspend fun doWork() = withContext(Dispatchers.IO) {
      val location = getLocation()
      if (location == null) {
         if (runAttemptCount < MAX_ATTEMPT) { // max_attempt = 3
            Result.retry()
         } else {
            Result.failure()
         }
      } else {
         Log.d(TAG, "doWork success $location")
         Result.success()
      }
    }
    
    private suspend fun getLocation(): Location? = withTimeoutOrNull(TIMEOUT) {
       suspendCancellableCoroutine<Location?> { continuation ->
          val intent = PendingIntent.getBroadcast(context, REQUEST_CODE, Intent(ACTION), 0)
          val receiver = object : BroadcastReceiver() {
              override fun onReceive(context: Context?, data: Intent?) {
                  if (data?.action != ACTION) return
                  val lastLocation = LocationResult.extractResult(data)?.lastLocation
                  Log.e(TAG, "Get lastLocation success $lastLocation")
                  fusedLocationClient.removeLocationUpdates(intent)
                  context?.unregisterReceiver(this)
                  continuation.resume(lastLocation)
              }
        }
        context.registerReceiver(receiver, IntentFilter(ACTION))
        val request = LocationRequest().apply { priority = LocationRequest.PRIORITY_HIGH_ACCURACY }
        fusedLocationClient.requestLocationUpdates(request, intent)
        continuation.invokeOnCancellation {
            fusedLocationClient.removeLocationUpdates(intent)
            context.unregisterReceiver(receiver)
        }
    }
    
    companion object {
            val TAG = LocationWorker::class.java.simpleName
            const val LOCATION_WORKER_TAG = "LOCATION_WORKER_TAG"
            const val MAX_ATTEMPT = 3
            private const val ACTION = "my.background.location"
            private const val TIMEOUT = 60_000L
            private const val REQUEST_CODE = 888
        }
    }

Pre-condition:

Why the lastknown location not updated ?

I also tried this demo https://github.com/pratikbutani/LocationTracker-WorkManager/ . However, the problem is same, lastknown location is not updated.

Upvotes: 2

Views: 1631

Answers (1)

ADITYA RANADE
ADITYA RANADE

Reputation: 293

The previous location gets cached. Clear the cache before you store the new location in lastknown location

Upvotes: 0

Related Questions