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

Google Maps API显示当前位置异常及权限替代方案咨询

问题解决方案

1. 用registerForActivityResult替代Fragment中废弃的onRequestPermissionsResult

在Fragment中,直接通过registerForActivityResult声明权限请求启动器,替代原有的onRequestPermissionsResult方法,所有权限处理逻辑都在启动器回调中完成:

步骤1:声明权限请求Launcher

在HomeFragment类中添加成员变量:

import androidx.activity.result.contract.ActivityResultContracts
import android.Manifest
import android.widget.Toast
import androidx.core.content.ContextCompat

private val requestLocationPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        // 权限授予成功,执行地图定位初始化
        setupMapLocation()
    } else {
        // 权限被拒绝,提示用户
        Toast.makeText(requireContext(), "需要位置权限才能显示当前位置", Toast.LENGTH_SHORT).show()
    }
}

步骤2:发起权限请求

在需要检查权限的地方(比如地图初始化后)调用:

fun checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // 未授权,发起请求
        requestLocationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
    } else {
        // 已授权,直接初始化定位
        setupMapLocation()
    }
}

这样就完全替代了onRequestPermissionsResult的逻辑,无需再重写该废弃方法。


2. 修复Google Maps显示默认位置(山景城)而非德国当前位置的问题

已授权位置权限但显示默认位置,通常是因为没有主动获取并移动相机到当前位置,或者设备定位服务未启用。以下是具体修复步骤:

步骤1:添加必要依赖与权限

确保build.gradle(Module级)中添加了Fused Location Provider依赖:

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

在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />

<!-- 确保已配置Google Maps API密钥 -->
<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="你的API密钥"/>

步骤2:实现定位并移动相机到当前位置

在HomeFragment中通过FusedLocationProviderClient获取当前位置,并控制地图相机移动:

import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import android.os.Looper

private lateinit var googleMap: GoogleMap
private lateinit var fusedLocationClient: FusedLocationProviderClient

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())
    
    // 初始化地图
    val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
    mapFragment.getMapAsync(this)
}

override fun onMapReady(map: GoogleMap) {
    googleMap = map
    // 启用我的位置图层和按钮
    googleMap.isMyLocationEnabled = true
    googleMap.uiSettings.isMyLocationButtonEnabled = true
    
    // 检查权限并获取当前位置
    checkLocationPermission()
}

private fun setupMapLocation() {
    if (ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        // 获取最后已知位置
        fusedLocationClient.lastLocation.addOnSuccessListener { location ->
            location?.let {
                val currentLatLng = LatLng(it.latitude, it.longitude)
                // 移动相机到当前位置,缩放级别15
                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f))
            } ?: run {
                // 如果lastLocation为空,请求实时位置更新
                val locationRequest = LocationRequest.create().apply {
                    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
                    interval = 10000
                    fastestInterval = 5000
                }
                fusedLocationClient.requestLocationUpdates(
                    locationRequest,
                    locationCallback,
                    Looper.getMainLooper()
                )
            }
        }
    }
}

// 位置更新回调
private val locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        super.onLocationResult(locationResult)
        val location = locationResult.lastLocation
        location?.let {
            val currentLatLng = LatLng(it.latitude, it.longitude)
            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f))
            // 获取到位置后停止更新
            fusedLocationClient.removeLocationUpdates(this)
        }
    }
}

额外检查点

  • 真机:确保设备开启了高精度定位模式,并允许应用访问位置。
  • 模拟器:在模拟器设置中添加德国的模拟坐标(比如柏林:52.5200° N, 13.4050° E),或者使用模拟器的位置模拟功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:33:13