尝试获取位置时避免 Google 的提示

Avoiding Google's prompt when trying to get location

我正在使用 Flutter 的 location 插件开发一个简单的应用程序,其中一些代码基于 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;
}

如插件页面所示,我将 ACCESS_FINE_LOCATION 添加到 Android 清单中。

问题是,当我在 phone 上测试应用程序时(使用 Android 9,以防它相关),即使位置 已启用并且我有 GPS 信号,执行上述代码会出现以下提示:

提示为:"For a better experience, turn on device location, which uses Google's location service.",有两个按钮:"NO THANKS" "OK".

这对用户非常不友好:位置已经来自 GPS,无需再打扰用户。

问题出在哪里,如何避免该提示?我更喜欢报告 "unknown location" 而不是显示提示。

编辑:请注意,提示与通知用户位置将被使用无关,但它是Google 侵犯隐私的功能,当您单击“确定”时,启用 Google 定位精度,如下所述(隐藏在“设置”菜单的深处):

上图显示:"Improve Location Accuracy",带有切换按钮。 Google 定位精度:Google 的定位服务通过使用 Wi‑Fi 和移动网络来帮助估计您的位置,从而提高定位精度。当您的设备开启时,匿名位置数据将发送到 Google。

单击第一个提示即可启用此功能,如果用户不想将其位置数据发送到 Google,则必须手动禁用此功能。禁用它并尝试再次获取位置会导致相同的提示,因此它绝对与警告用户位置数据的使用无关。此外,如果 Google 在使用应用程序 之前 启用了定位精度,提示永远不会出现在第一位,这可能是大多数开发人员从未注意到它的原因。

我知道无需 启用Google 定位精度即可获取位置数据,因为大多数应用程序都这样做。但是不知道提示是从哪里来的:难道是Flutter的location plugin?我使用的是 Android 9 SDK 吗?或者示例代码?

问题似乎出在 location 插件上。我试过换成geolocator,修改来电代码,这次没有出现这样的提示

我尝试在询问位置之前降低精度,但 location 插件仍然显示提示。在所有情况下,必须有一些硬连接的底层代码来请求 Google 位置精度。

要是Google能提供一种永久禁用系统提示的方法就好了 "no"(这是几个 Android 版本的问题),我可能已经给了他们怀疑的好处。

我今天遇到了同样的问题,但通过定位有问题的表达式解决了这个问题,并添加了一个 if 语句来检查应用程序的位置权限是否被授予。

这是我在 Kotlin 中的代码,有问题的表达式在全部大写的注释下方:

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")
    }
}

现在我的解决方案可能并不完全适用于您的问题,但我认为它应该足以解决您的问题。但是,在请求用户位置时,您可能需要重新编写代码。

此外,我不太确定是否使用 Flutter 的插件进行定位,但在您和其他人的情况下,我建议在请求用户位置时遵循开发人员文档。也许它也适用于 Flutter: https://developer.android.com/training/location/change-location-settings