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

Gradle迁移至Kotlin DSL后Google Maps API权限异常求助

问题分析与解决方案

这个错误和Gradle Kotlin DSL完全无关——权限机制是Android系统的核心逻辑,和构建脚本的语言没有关联。你遇到的问题本质是:Google Maps的setMyLocationEnabled()方法会主动检查权限状态,即使你已经在Manifest中声明权限、且能通过其他API获取位置,只要调用该方法时权限未被用户授予,就会触发这个错误。

核心原因

Android 6.0(API 23)及以上版本中,ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION属于危险权限,仅在Manifest中声明是不够的,必须在运行时向用户申请并获得授权。你提到能正常定位,大概率是通过FusedLocationProviderClient等定位API获取位置,但这些API的权限检查逻辑和Google Maps的setMyLocationEnabled()是分开的——后者会强制校验权限状态。

解决方案

在调用setMyLocationEnabled(true)之前,必须确保已获取至少一个位置权限。以下是标准实现方式:

1. 使用Activity Result API(推荐,适配新版Android)

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import androidx.activity.result.contract.ActivityResultContracts

class MainActivity : AppCompatActivity(), OnMapReadyCallback {
    private var googleMap: GoogleMap? = null
    private val LOCATION_PERMISSIONS = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )

    // 注册权限请求回调
    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        val hasFinePermission = permissions[Manifest.permission.ACCESS_FINE_LOCATION] ?: false
        val hasCoarsePermission = permissions[Manifest.permission.ACCESS_COARSE_LOCATION] ?: false

        if (hasFinePermission || hasCoarsePermission) {
            // 权限授予成功,开启我的位置
            googleMap?.isMyLocationEnabled = true
        } else {
            // 权限被拒绝,提示用户
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    override fun onMapReady(map: GoogleMap) {
        googleMap = map
        checkAndRequestLocationPermissions()
    }

    private fun checkAndRequestLocationPermissions() {
        val hasFinePermission = ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
        val hasCoarsePermission = ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED

        if (hasFinePermission || hasCoarsePermission) {
            googleMap?.isMyLocationEnabled = true
        } else {
            // 申请权限
            requestPermissionLauncher.launch(LOCATION_PERMISSIONS)
        }
    }
}

2. 旧版权限回调方式(兼容API < 33)

如果需要兼容更老的系统版本,可以使用onRequestPermissionsResult:

private val LOCATION_PERMISSION_REQUEST_CODE = 1001

private fun checkAndRequestLocationPermissions() {
    val hasFinePermission = ContextCompat.checkSelfPermission(
        this,
        Manifest.permission.ACCESS_FINE_LOCATION
    ) == PackageManager.PERMISSION_GRANTED
    val hasCoarsePermission = ContextCompat.checkSelfPermission(
        this,
        Manifest.permission.ACCESS_COARSE_LOCATION
    ) == PackageManager.PERMISSION_GRANTED

    if (hasFinePermission || hasCoarsePermission) {
        googleMap?.isMyLocationEnabled = true
    } else {
        requestPermissions(LOCATION_PERMISSIONS, LOCATION_PERMISSION_REQUEST_CODE)
    }
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
        val hasFine = grantResults.getOrNull(0) == PackageManager.PERMISSION_GRANTED
        val hasCoarse = grantResults.getOrNull(1) == PackageManager.PERMISSION_GRANTED
        if (hasFine || hasCoarse) {
            googleMap?.isMyLocationEnabled = true
        }
    }
}

额外注意事项

  • 确保在onMapReady回调之后再处理权限逻辑,避免googleMap实例为空。
  • 如果用户拒绝权限,可以在回调中引导用户到应用设置页面开启权限。
  • 你的Manifest配置是正确的,不需要修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:15:21