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

使用FusedLocationProvider请求位置时遇Task未完成异常,求解决方案

问题分析与解决方案

为什么会触发这个异常?

fusedLocationClient.lastLocation是一个异步Task,它不会立即返回设备位置,而是在后台完成位置查询后,通过addOnSuccessListener回调返回结果。你在调用addOnSuccessListener后立刻尝试获取callbacklocation.result,此时Task还处于未完成状态,直接访问result就会抛出IllegalStateException。

正确实现步骤

结合Jetpack Compose的状态管理,我们需要用可观察状态保存位置,当异步任务完成后更新状态,Compose会自动重组UI展示地图。同时还要处理权限、位置为空的边界情况:

1. 修正后的完整代码

class MainActivity : AppCompatActivity() {

    @SuppressLint("MissingPermission")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        setContent {
            MapsTestTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    // 用Compose状态保存位置,初始为null
                    val userLocation = remember { mutableStateOf<LatLng?>(null) }

                    // 启动异步位置请求,仅在Composable首次加载时执行
                    LaunchedEffect(Unit) {
                        fusedLocationClient.lastLocation
                            .addOnSuccessListener { location: Location? ->
                                location?.let {
                                    userLocation.value = LatLng(it.latitude, it.longitude)
                                }
                            }
                            .addOnFailureListener {
                                // 处理位置请求失败的情况,比如权限不足或无缓存位置
                                Log.e("LocationError", "获取位置失败: ${it.message}")
                            }
                    }

                    // 根据位置状态展示对应UI
                    userLocation.value?.let { location ->
                        ShowLastLocation(location)
                    } ?: run {
                        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                            Text(text = "正在获取位置...")
                        }
                    }
                }
            }
        }
    }

    @Composable
    fun ShowLastLocation(location: LatLng) {
        GoogleMap(
            modifier = Modifier.fillMaxSize(),
            cameraPositionState = rememberCameraPositionState {
                position = CameraPosition.fromLatLngZoom(location, 10f)
            }
        ) {
            Marker(
                state = MarkerState(position = location),
                title = "你的位置"
            )
        }
    }
}

2. 关键改进点

  • Compose状态管理:用mutableStateOf保存位置,位置更新时Compose自动触发UI重组。
  • 异步操作规范:用LaunchedEffect包裹位置请求,确保仅在Composable首次加载时执行一次,避免重复请求。
  • 回调正确处理:在addOnSuccessListener中更新状态,而非直接访问未完成的Task结果。
  • 边界情况处理:增加位置为空时的加载提示,以及失败回调捕获错误。
  • 权限提示:实际开发中要移除@SuppressLint("MissingPermission"),先通过ActivityResultContracts.RequestPermission完成运行时权限申请,再发起位置请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:55:19