9

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?

JJJ
  • 32,902
  • 20
  • 89
  • 102
anol
  • 8,264
  • 3
  • 34
  • 78
  • I think this is designed to notify the user that their location is going to be used, and give them a choice. It's not really "horribly user-unfriendly" if it involves giving the user the right of choice and only displays once. Display "unknown location" if they decline. – Aaron Jun 08 '19 at 23:13
  • 1
    @Aaron No, the prompt is not designed to notify the user that the app uses location. I edited the question to clarify it: the prompt is only about Google Location Accuracy, which is an unnecessary and privacy-invading feature. Almost all apps I have do not require it, so it must either be Flutter's location plugin, or the Android 9 SDK which I've set up. – anol Jun 09 '19 at 07:03
  • Oh I see, I do apologise – Aaron Jun 09 '19 at 07:04
  • No need to apologize, your comment is a good illustration why Google is using these kinds of dark patterns. It's appalling that writing a non-dysfunctional app (that is, privacy-respectful) is becoming harder and harder. – anol Jun 09 '19 at 07:09
  • This one is also driving me nuts as well. I only encountered this on emulator. I really hate this. As after I press ok, nothing happens now on my app. I need to know the user accepted it. – Neon Warge Nov 04 '19 at 08:13
  • How to override language in that dialog without using one from system settings? – I.Step Aug 07 '21 at 11:11

2 Answers2

5

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.

anol
  • 8,264
  • 3
  • 34
  • 78
  • 2
    I'm having the same issue, oddly only in the Android emulator but not when I test on a physical device. Is there any known workaround on Location(), rather than having to replace it with geolocator? – puntofisso Oct 25 '19 at 18:56
0

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

Adam Bridges
  • 306
  • 3
  • 7