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

Jetpack Compose中如何用FusedLocationProviderClient单次查询位置?

在Jetpack Compose中实现单次定位查询

方法一:直接使用getCurrentLocation(推荐)

Google Play Services Location库提供了getCurrentLocation方法,专门用于获取单次位置,无需手动管理监听注销。结合协程能在Compose中更优雅地实现:

首先初始化FusedLocationProviderClient:

val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)

然后在Compose的协程作用域(比如LaunchedEffect)中调用:

LaunchedEffect(Unit) {
    val locationRequest = LocationRequest.create().apply {
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        timeoutMillis = 10000 // 设置10秒超时
    }

    // 先检查定位权限
    if (ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        try {
            // 用suspendCoroutine包装Task,避免回调嵌套
            val location = suspendCoroutine<Location?> { cont ->
                fusedLocationClient.getCurrentLocation(
                    locationRequest,
                    null // 无需LocationSettingsRequest可传null,按需添加
                ).addOnSuccessListener { loc ->
                    cont.resume(loc)
                }.addOnFailureListener { e ->
                    cont.resumeWithException(e)
                }
            }

            location?.let {
                // 处理获取到的单次位置
                Log.d("Location", "单次定位成功:${it.latitude}, ${it.longitude}")
            } ?: run {
                Log.d("Location", "未获取到有效位置")
            }
        } catch (e: Exception) {
            Log.e("Location", "定位失败", e)
        }
    }
}

如果引入kotlinx-coroutines-play-services依赖,还能直接用await()简化代码:

// 先添加依赖:implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3"
val location = fusedLocationClient.getCurrentLocation(locationRequest, null).await()

方法二:在持续监听中获取位置后注销回调

如果你已经在用requestLocationUpdates做持续监听,只需在LocationCallback的onLocationResult中拿到有效位置后,调用removeLocationUpdates注销即可:

val locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        super.onLocationResult(locationResult)
        locationResult.lastLocation?.let { location ->
            // 处理获取到的位置
            Log.d("Location", "获取到位置:${location.latitude}, ${location.longitude}")
            
            // 注销回调,停止后续位置更新
            fusedLocationClient.removeLocationUpdates(this)
        }
    }
}

// 在LaunchedEffect中启动监听
LaunchedEffect(Unit) {
    if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        val locationRequest = LocationRequest.create().apply {
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            interval = 1000 // 初始监听间隔,拿到位置后就会注销
        }
        fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
    }
}

注意事项

  • 必须先申请并获取ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,否则会触发权限异常。
  • getCurrentLocation可能返回null(比如设备未开定位、无信号),需做好判空处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:42:49