I am developing a simple app using Flutter's location plugin, with some code based on their sample code:

var location = new Location();
try {
  _currentLocation = await location.getLocation();
} on PlatformException catch (e) {
  if (e.code == 'PERMISSION_DENIED') {
    _locationMsg = 'Permission denied';
  }
  _currentLocation = null;
}

As indicated in the plugin page, I added ACCESS_FINE_LOCATION to the Android manifest.

The problem is, when I test the app on a phone (with Android 9, in case it's relevant), even though location is enabled and I have a GPS signal, executing the above code results in the following prompt:

Prompt about enabling Google's location service

The prompt reads: "For a better experience, turn on device location, which uses Google's location service.", with two buttons: "NO THANKS" and "OK".

This is horribly user-unfriendly: location is already coming from the GPS, there is no need to further bother the user.

Where is the problem coming from, and how can I avoid that prompt? I prefer reporting "unknown location" than having the prompt displayed.

Edit: Note that the prompt is not related to notifying the user that the location will be used, but it is a Google privacy-invading feature that, when you click OK, enables Google Location Accuracy, as described below (hidden deep in a Settings menu):

Google Location Accuracy description

The above image reads: "Improve Location Accuracy", with a toggle button. Google Location Accuracy: Google’s location service improves location accuracy by using Wi‑Fi and mobile networks to help estimate your location. Anonymous location data will be sent to Google when your device is on.

Clicking on the first prompt enables this, which the user then has to manually disable if they don't want to send their location data to Google. Disabling it and trying to get the location again results in the same prompt, so it is definitely not related to warning the user about the usage of location data. Also, if Google Location Accuracy is enabled before using the app, the prompt never appears in the first place, which is probably why most developers never notice it.

I know it is possible to get location data without enabling Google Location Accuracy, since most apps do it. But I don't know where the prompt comes from: is it Flutter's location plugin? The fact that I am using an Android 9 SDK? Or the sample code?


Solution 1: anol

It seems the issue is coming from the location plugin. I tried replacing it with geolocator, and modifying the caller code, and this time no such prompt appears.

I tried lowering the accuracy before asking for location, but the location plugin still displays the prompt. There must be some underlying code which is hardwired to request Google Location Accuracy in all cases.

If only Google would provide a way to permanently disable the prompt with a systematic "no" (this has been an issue for several Android releases), I might have given them the benefit of doubt.


Solution 2: Adam Bridges

I was having this same issue today but solved it by locating the offending expression and added an if statement to check whether the app's location permission was granted.

Here is my code in Kotlin and the offending expression is under the note in all caps:

private fun checkLocationPermission() : Boolean = (ContextCompat.checkSelfPermission(
        requireContext(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)

private fun startLocationRequests() {
    val locationRequest = LocationRequest.create()?.apply {
        interval = 10000
        fastestInterval = 5000
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }

    val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest!!)
    val client: SettingsClient = LocationServices.getSettingsClient(requireActivity())
    val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())

    task.addOnSuccessListener { locationSettingsResponse ->
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...

        if (checkLocationPermission()) {
            locationPermissionGranted = true
            fusedLocationProviderClient.requestLocationUpdates(
                    locationRequest, locationCallback, Looper.getMainLooper())
        }
    }

    task.addOnFailureListener { exception ->
        if (exception is ResolvableApiException){
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                // IF STATEMENT THAT PREVENTS THE DIALOG FROM PROMPTING.
                    if (checkLocationPermission()) { 
                        exception.startResolutionForResult(
                            requireActivity(),
                            REQUEST_CHECK_SETTINGS
                        )
                    }
            } catch (sendEx: IntentSender.SendIntentException) {
                // Ignore the error.
            }
        }
        Timber.i("Location Listener failed")
    }
}

Now my solution may not exactly apply to your problem but I think it should be enough to learn from to solve your problem. However, you may need to redo your code when it comes to requesting a user's location, though.

Also, I'm not so sure about using Flutter's plugin for location but in your case and others, I would recommend following the developer documentation when it comes to requesting a user's location. Perhaps it's applicable to Flutter too: https://developer.android.com/training/location/change-location-settings