androidandroid-gpsandroid-11

Android 11: how to get current location


I want to get the current location of the device when the user clicks something. I do not need continuous updates.

The FusedLocationProviderClient.getLastLocation() is not an option for me because it only returns the last location, which can be different from the current location, or null, which happens way more often than the documentation made me believe.

This code below, does the job I want it to do perfectly until Android 10. On Android 11 it doesn't work anymore.

@RequiresPermission(value = Manifest.permission.ACCESS_FINE_LOCATION)
private fun locationPermissionGranted() {
    val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireContext())
    
    //create location request
    val locationRequest = LocationRequest.create().apply {
        interval = 1000L
        fastestInterval = 100L
        numUpdates = 1
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
    
    //create callback
    val mLocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            useLocation(locationResult?.lastLocation)
            fusedLocationProviderClient.removeLocationUpdates(this)
        }
        
        override fun onLocationAvailability(locationAvailability: LocationAvailability?) {
            if (locationAvailability?.isLocationAvailable == false) {
                Toast.makeText(context, R.string.error_couldnt_get_location, Toast.LENGTH_SHORT).show()
                fusedLocationProviderClient.removeLocationUpdates(this)
            } else {
                super.onLocationAvailability(locationAvailability)
            }
        }
    }
    
    //request location update
    fusedLocationProviderClient
        .requestLocationUpdates(locationRequest, mLocationCallback, Looper.getMainLooper())
        .let { task ->
            task.addOnCanceledListener {
                Toast.makeText(context, R.string.error_couldnt_get_location, Toast.LENGTH_SHORT).show()
            }
            task.addOnFailureListener { exception ->
                Toast.makeText(context, R.string.error_couldnt_get_location, Toast.LENGTH_SHORT).show()
            }
            task.addOnSuccessListener {}
        }
}

On Android 11 onLocationResult doesn't ever get called. Even if I removed everything in onLocationAvailability, onLocationResult still wouldn't get called.

So, how do I request the devices current position correctly on Android 11?

Edit:

FusedLocationProviderClient.getCurrentLocation() doesn't work either. None of the callbacks of the task are being called.


Solution

  • I was wrong. Both FusedLocationProviderClient.getCurrentLocation() and FusedLocationProviderClient.requestLocationUpdates() do work on Android 11. They are just extremely slow unless the user has "Wi-Fi Scanning", "Bluetooth Scanning" and most importantly "Google Location Accuracy" turned on. It is not enough for the user to have activated "use Location".