You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中getCurrentLocation函数返回初始值问题求助

问题原因与解决方案

问题核心分析

你遇到的问题本质是异步操作的执行顺序问题:

  • fusedLocationProviderClient.lastLocation.addOnCompleteListener是异步任务,它的回调代码会在后台获取到位置信息后才执行。
  • 但你的getCurrentLocation函数是同步执行的——在回调还没来得及更新DBLatitude和DBLongitude之前,函数就已经执行到return语句,返回了初始的0.0值。
  • 而UI控件能正常显示,是因为回调执行时确实更新了binding.tvLatitude和binding.tvLongitude,这时候函数的返回值已经无关紧要了。

解决方案1:使用Kotlin协程(推荐)

将函数改为挂起函数,利用Tasks.await()把异步任务转为同步等待,确保获取到位置后再返回值:

private suspend fun getCurrentLocation(): String {
    var DBLatitude: Double = 0.0
    var DBLongitude: Double = 0.0

    if (checkPermissions()) {
        if (isLocationEnabled()) {
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                checkPermissions()
            }
            try {
                // 等待异步任务完成,获取位置结果
                val location = Tasks.await(fusedLocationProviderClient.lastLocation)
                if (location == null) {
                    Toast.makeText(this, "Null obtido", Toast.LENGTH_SHORT).show()
                } else {
                    binding.tvLatitude.text = "" + location.latitude
                    binding.tvLongitude.text = "" + location.longitude

                    DBLatitude = location.latitude
                    DBLongitude = location.longitude
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this, "获取位置失败", Toast.LENGTH_SHORT).show()
            }
        } else {
            Toast.makeText(this, "Ligue a localização", Toast.LENGTH_SHORT).show()
            val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
            startActivity(intent)
        }
    } else {
        requestPermission()
    }
    return "" + DBLatitude + " " + DBLongitude
}

调用方式

需要在协程作用域中调用该函数,比如使用页面的生命周期协程:

lifecycleScope.launch {
    val locationStr = getCurrentLocation()
    // 此处拿到的locationStr就是正确的经纬度,可直接发送到数据库
}

解决方案2:使用回调接口

如果不想用协程,可以定义回调接口,在位置获取完成后再处理结果:

1. 定义回调接口

interface LocationCallback {
    fun onLocationReceived(locationStr: String)
}

2. 修改获取位置的函数

private fun getCurrentLocation(callback: LocationCallback) {
    var DBLatitude: Double = 0.0
    var DBLongitude: Double = 0.0

    if (checkPermissions()) {
        if (isLocationEnabled()) {
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                checkPermissions()
            }
            fusedLocationProviderClient.lastLocation.addOnCompleteListener(this) { task ->
                val location = task.result

                if (location == null) {
                    Toast.makeText(this, "Null obtido", Toast.LENGTH_SHORT).show()
                    callback.onLocationReceived("$DBLatitude $DBLongitude")
                } else {
                    binding.tvLatitude.text = "" + location.latitude
                    binding.tvLongitude.text = "" + location.longitude

                    DBLatitude = location.latitude
                    DBLongitude = location.longitude
                    // 获取到位置后调用回调返回结果
                    callback.onLocationReceived("$DBLatitude $DBLongitude")
                }
            }
        } else {
            Toast.makeText(this, "Ligue a localização", Toast.LENGTH_SHORT).show()
            val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
            startActivity(intent)
            callback.onLocationReceived("$DBLatitude $DBLongitude")
        }
    } else {
        requestPermission()
        callback.onLocationReceived("$DBLatitude $DBLongitude")
    }
}

3. 调用方式

getCurrentLocation(object : LocationCallback {
    override fun onLocationReceived(locationStr: String) {
        // 此处拿到正确的经纬度字符串,执行发送到数据库的逻辑
    }
})

内容的提问来源于stack exchange,提问作者Bruno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:10:30