Kotlin中Google地图定位权限缺失问题求助
问题排查与解决
你的核心问题是权限请求后没有处理授权回调——调用requestPermissions后直接return,当用户点击允许权限时,代码不会自动重新执行setUpMap里的定位逻辑,导致后续调用isMyLocationEnabled和getLastLocation时依然处于无权限状态。
解决步骤:
添加权限授权回调处理
在MapActivity中重写onRequestPermissionsResult方法,当用户授权成功后,重新执行定位逻辑:override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { // 权限授予成功,重新初始化地图定位 if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { setUpMap() } } }优化权限判断逻辑(可选)
同时检查两种定位权限,提升兼容性:private fun setUpMap(){ val hasFineLocPerm = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED val hasCoarseLocPerm = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED if (!hasFineLocPerm && !hasCoarseLocPerm){ ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE) return } // 后续地图定位逻辑 mMap.isMyLocationEnabled = true mMap.mapType = GoogleMap.MAP_TYPE_NORMAL fusedLocationClient.lastLocation.addOnSuccessListener { location -> if (location != null){ lastLocation = location val currentLatLng = LatLng(location.latitude, location.longitude) placeMarkerOnMap(currentLatLng) mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f)) } } }Manifest配置确认
你的AndroidManifest.xml权限配置完全正确,已经添加了ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION,无需修改。如果应用目标SDK为31(Android 12)及以上且需要后台持续定位,才需额外添加ACCESS_BACKGROUND_LOCATION权限,当前场景不需要。
修改后的完整MapActivity代码:
import android.Manifest import android.content.pm.PackageManager import android.location.Location import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import androidx.core.app.ActivityCompat import com.google.android.gms.location.FusedLocationProviderClient 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 com.google.android.gms.maps.model.Marker import com.google.android.gms.maps.model.MarkerOptions import com.yourpackage.name.databinding.ActivityMapsBinding class MapsActivity : AppCompatActivity(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener { private lateinit var mMap: GoogleMap private lateinit var binding: ActivityMapsBinding private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var lastLocation: Location companion object { private const val LOCATION_PERMISSION_REQUEST_CODE = 1 } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMapsBinding.inflate(layoutInflater) setContentView(binding.root) val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) } override fun onMapReady(googleMap: GoogleMap) { mMap = googleMap mMap.uiSettings.isZoomControlsEnabled = true mMap.setOnMarkerClickListener(this) setUpMap() } override fun onMarkerClick(p0: Marker): Boolean = false private fun setUpMap(){ val hasFineLocPerm = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED val hasCoarseLocPerm = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED if (!hasFineLocPerm && !hasCoarseLocPerm){ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE) return } mMap.isMyLocationEnabled = true mMap.mapType = GoogleMap.MAP_TYPE_NORMAL fusedLocationClient.lastLocation.addOnSuccessListener { location -> if (location != null){ lastLocation = location val currentLatLng = LatLng(location.latitude, location.longitude) placeMarkerOnMap(currentLatLng) mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f)) } else { Toast.makeText(this, "无法获取当前位置", Toast.LENGTH_SHORT).show() } } } private fun placeMarkerOnMap(currentLatLng: LatLng) { val markerOptions = MarkerOptions().position(currentLatLng).title("当前位置") mMap.addMarker(markerOptions) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { if (grantResults.isNotEmpty() && grantResults.any { it == PackageManager.PERMISSION_GRANTED }) { setUpMap() } else { Toast.makeText(this, "需要定位权限才能显示当前位置", Toast.LENGTH_SHORT).show() } } } }
注意事项:
- 建议在真实设备上测试定位功能,部分模拟器可能无法获取有效定位数据
- 如果用户拒绝权限并勾选「不再询问」,可添加逻辑引导用户前往应用设置开启权限
内容的提问来源于stack exchange,提问作者Pragyanshree Das
相关产品推荐
相关产品推荐

