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

Kotlin调用FusedLocationProviderClient获取位置返回null问题排查

问题原因分析

从日志可以确认位置权限已经正常授予,返回location=null的核心原因如下:

  • FusedLocationProviderClient.lastLocation 接口本身仅读取系统缓存的历史位置记录,不会主动触发定位。当设备满足以下任意一种情况时,缓存为空就会返回null:
    • 设备刚重启完成,还没有任何应用触发过定位
    • 系统位置服务刚被手动开启,还未生成过位置缓存
    • 设备的定位缓存被系统主动清除
  • 额外排查点:确认设备的全局位置开关(下拉状态栏的定位按钮)已经开启,仅授予应用位置权限但关闭系统全局定位也会返回null
解决方案

方案1:优先检查并引导开启系统位置服务

增加位置服务可用性检查逻辑,未开启时跳转到系统设置页引导用户开启。

方案2:主动请求实时位置更新替代仅读取缓存

不要完全依赖lastLocation接口,主动触发一次实时定位,拿到有效位置后再停止定位即可,示例修改代码如下:

首先确保app模块的build.gradle已添加位置服务依赖:

dependencies {
    implementation 'com.google.android.gms:play-services-location:21.0.1'
}

修改后的Activity代码示例:

class MainActivity : AppCompatActivity() {

    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var text: TextView
    // 定位请求配置
    private val locationRequest = LocationRequest.create().apply {
        interval = 10000
        fastestInterval = 5000
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        numUpdates = 1 // 只请求一次定位结果
    }
    // 定位结果回调
    private val locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            super.onLocationResult(locationResult)
            val location = locationResult.lastLocation
            if (location != null) {
                text.text = "My location ${location.latitude}, ${location.longitude}"
                // 拿到结果后停止定位节省资源
                fusedLocationClient.removeLocationUpdates(this)
            } else {
                text.text = "location = null"
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text = findViewById(R.id.textView)
        val button: Button = findViewById(R.id.button)
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        val requestMultiplePermissions = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
            permissions.entries.forEach {
                Log.e("DEBUG", "${it.key} = ${it.value}")
            }
        }
        button.setOnClickListener {
            requestLocation()
        }
        requestMultiplePermissions.launch(
            arrayOf(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
        )
    }

    private fun requestLocation() {
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            text.text = "do not grants the permission"
            return
        }
        // 先尝试读取缓存,缓存为空再主动请求实时定位
        fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
            if (location != null) {
                text.text = "My location ${location.latitude}, ${location.longitude}"
            } else {
                // 缓存为空,触发实时定位
                fusedLocationClient.requestLocationUpdates(
                    locationRequest,
                    locationCallback,
                    Looper.getMainLooper()
                )
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 页面销毁时移除定位回调避免内存泄漏
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:36:07