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

如何在最新版Jetpack Compose中标记MapBox当前用户位置

解决Jetpack Compose中MapBox无法显示当前用户位置的问题

1. 添加并请求位置权限

首先在AndroidManifest.xml中声明位置权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

在Compose中动态请求权限,通过ActivityResultContracts实现:

@Composable
fun MapUserLocation() {
    val context = LocalContext.current
    val activity = context.findActivity() ?: return

    val permissionLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        val hasFineLocation = permissions[android.Manifest.permission.ACCESS_FINE_LOCATION] ?: false
        val hasCoarseLocation = permissions[android.Manifest.permission.ACCESS_COARSE_LOCATION] ?: false
        if (hasFineLocation || hasCoarseLocation) {
            // 权限已获取,地图位置组件可正常工作
        }
    }

    LaunchedEffect(Unit) {
        val hasFineLocation = ContextCompat.checkSelfPermission(
            context,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
        val hasCoarseLocation = ContextCompat.checkSelfPermission(
            context,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED

        if (!hasFineLocation && !hasCoarseLocation) {
            permissionLauncher.launch(
                arrayOf(
                    android.Manifest.permission.ACCESS_FINE_LOCATION,
                    android.Manifest.permission.ACCESS_COARSE_LOCATION
                )
            )
        }
    }

    Column(modifier = Modifier.fillMaxSize()) {
        MapBoxMap(modifier = Modifier.fillMaxSize())
    }
}

// 扩展函数:从Context获取Activity
fun Context.findActivity(): Activity? = when (this) {
    is Activity -> this
    is ContextWrapper -> baseContext.findActivity()
    else -> null
}

2. 配置MapBox LocationComponent

原代码中注释了位置组件的配置逻辑,需在地图样式加载完成后启用并配置LocationComponent,修改MapBoxMap函数:

@Composable
fun MapBoxMap(
    modifier: Modifier = Modifier
) {
    val context = LocalContext.current
    val locationMarker = remember {
        context.getDrawable(R.drawable.circle_icon)?.toBitmap()
    }
    val mapView = remember { MapView(context) }
    val pointAnnotationManager = remember { mutableStateOf<PointAnnotationManager?>(null) }

    AndroidView(
        factory = { context ->
            mapView.apply {
                mapboxMap.loadStyle(Style.MAPBOX_STREETS) { style ->
                    pointAnnotationManager.value = annotations.createPointAnnotationManager()

                    locationMarker?.let {
                        style.addImage("marker-image-id", it)
                    }

                    // 配置位置组件
                    val locationComponent = mapboxMap.locationComponent
                    locationComponent.apply {
                        // 初始化位置组件
                        activateLocationComponent(
                            LocationComponentActivationOptions.builder(context, style).build()
                        )
                        // 启用位置追踪
                        isLocationComponentEnabled = true
                        // 设置跟踪模式为GPS跟随
                        cameraMode = CameraMode.TRACKING_GPS
                        // 设置位置图标渲染模式
                        renderMode = RenderMode.NORMAL
                    }
                }
            }
        },
        modifier = modifier
    )
}

3. 修复语法错误

原代码中factory = { context -存在笔误,需修改为factory = { context ->。

4. 初始化MapBox

在自定义Application类中初始化MapBox(替换为你的官方访问令牌):

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Mapbox.getInstance(this, "你的MapBox访问令牌")
    }
}

并在AndroidManifest.xml中指定该Application:

<application
    android:name=".MyApplication"
    ...>
    ...
</application>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:09:54