Search code examples
androidkotlinandroid-workmanagerandroid-fusedlocation

Location Update from Work Manager Doesn't work


Recently I've been trying to implement the logic in order to get Location Updates from a FusedLocationProviderClient using Work Manager, every 15 mins (as that's the minimum background execution delay). However requestLocationUpdates() function from FusedLocationProviderClient is failing every 15 minutes, and I cannot get success result task from it, I'm always getting failed result. And when I print the exception from fusedlocationproviderclient it just prints "null"? Any help?

Fragment:

private fun addWorker(){
        val workRequest = PeriodicWorkRequestBuilder<MyWorker>(15, TimeUnit.MINUTES)
            .build()
        val workManager = WorkManager.getInstance(requireContext())
        workManager.enqueueUniquePeriodicWork(
            "MyMainWorker",
            ExistingPeriodicWorkPolicy.KEEP,
            workRequest
        )
}

Worker

class MyWorker(context: Context, wp: WorkerParameters) :
    Worker(context, wp) {

    private val LOCATION_UPDATE_INTERVAL = TimeUnit.MINUTES.toMillis(4)
    private val LOCATION_FASTEST_UPDATE_INTERVAL = TimeUnit.MINUTES.toMillis(2)

    private var ctx: Context = context

    override fun doWork(): Result {
        return if (getLocationUpdate()) {
            Log.d("MyWorker", "SUCCESS")
            Result.success()
        } else {
            Log.d("MyWorker", "FAILURE")
            Result.failure()
        }
    }

    @SuppressLint("MissingPermission")
    private fun getLocationUpdate(): Boolean {

       val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(ctx)

        val locationCallback = object : LocationCallback() {
            override fun onLocationResult(result: LocationResult?) {
                super.onLocationResult(result)
                result?.locations?.let { locations ->
                    for (location in locations) {
                        Log.d("MyWorker", "NEW Location: $location")
                    }
                }
            }
        }

        val locationRequest = LocationRequest().apply {
            interval = LOCATION_UPDATE_INTERVAL
            fastestInterval = LOCATION_FASTEST_UPDATE_INTERVAL
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }
        val result = fusedLocationProviderClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
        Log.d("MyWorker", result.exception?.message.toString())
        Log.d("MyWorker", result.exception?.cause.toString())
        Log.d("MyWorker", result.exception.toString())
        return result.isSuccessful
    }

Error

I/WM-WorkerWrapper: Worker result FAILURE for Work [ id=3fe5b78d-e0ed-4348-90b6-25c2c1f96bfd, tags={ com.example.testapp.MyWorker } ]


Solution

  • Note: The Google Play store has updated its policy concerning device location, restricting background location access to apps that need it for their core functionality and meet related policy requirements. Adopting these best practices doesn't guarantee Google Play approves your app's usage of location in the background.

    Learn more about the policy changes related to device location. https://support.google.com/googleplay/android-developer/answer/9799150