如何在 Kotlin 中调用 FusedLocationProviderClient 的 getCurrentLocation() 方法

Tyl*_*ler 4 android kotlin fusedlocationproviderclient

我正在尝试使用应用程序访问 Android 手机的位置信息,但似乎无法获取当前位置。我的代码如下:

fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())

val location_button = view.findViewById<ImageButton>(R.id.get_location)
location_button.setOnClickListener {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(requireActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED || ContextCompat.checkSelfPermission(requireActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED) {
            val permission = arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION)
            requestPermissions(permission, LOC_PERMISSION_CODE)
        }
        else {
            //permission already granted
            fusedLocationClient.lastLocation
                .addOnSuccessListener { location ->
                    // Got last known location. In some rare situations this can be null.
                    val latitude = location?.latitude
                    val longitude = location?.longitude
                    println(latitude)
                    println(longitude)
                }
                .addOnFailureListener {
                    Toast.makeText(requireActivity(), "Failed on getting current location",
                        Toast.LENGTH_SHORT).show()
                }
        }
    }
    else {
        fusedLocationClient.lastLocation
            .addOnSuccessListener { location : Location? ->
                // Got last known location. In some rare situations this can be null.
                println(location)
            }
    }
Run Code Online (Sandbox Code Playgroud)

第一次运行时,我成功地收到授予位置访问权限的提示,我就这样做了。然后它调用始终等于 null 的lastLocation。如果我再次运行该应用程序,我将被发送到第一个 else 块,在那里我打印出纬度和经度,但它们总是打印 null,即使我已成功授予位置访问权限,并调用最后一个位置。

我开始认为如果位置从未保存过,那么最后一个位置可能不起作用,并且我看到 FusedLocationProviderClient 类中有一个名为“getCurrentLocation()”的函数,但我不知道如何调用它。我错过了什么吗?

Bha*_*vin 5

正如 Gabe Sechan 建议的那样,如果您不希望自己的位置为空或每次都需要一个新位置,则必须调用新位置。

您可以使用 getCurrentLocation() 方法来完成此操作,该方法具有优先级和取消令牌。

val priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
val cancellationTokenSource = CancellationTokenSource()

fusedLocationClient.getCurrentLocation(priority, cancellationTokenSource.token)
            .addOnSuccessListener { location ->
                Log.d("Location", "location is found: $location")
            }
            .addOnFailureListener { exception ->
                Log.d("Location", "Oops location failed with exception: $exception")
            }
Run Code Online (Sandbox Code Playgroud)

您可以根据您的要求更改优先级,到目前为止我已经使用过,PRIORITY_BALANCED_POWER_ACCURACY因为它将使用 wifi 和 GPS 搜索位置来查找位置,如果您需要更高精度,您可以使用PRIORITY_HIGH_ACCURACY

我们提供取消令牌,就好像将来我们不需要位置,例如用户已关闭活动,因此我们将使用取消请求cancellationTokenSoure.cancel()