Android位置权限请求后grantResults为空但权限已授予的问题
嘿,我来帮你搞定这个让人困惑的问题!明明已经成功授予了位置权限,能正常用MyLocation图层,却弹出Toast说grantArray为空,这大概率是权限请求的回调逻辑出了问题,我给你分析几个常见原因和解决办法:
1. 混用了新旧权限请求API
这是最常见的坑!如果你用了AndroidX推荐的Activity Result API(也就是registerForActivityResult)来发起权限请求,同时又重写了旧的onRequestPermissionsResult方法,那旧的回调根本不会被触发,你在里面拿grantResults自然就是空的。
举个例子,如果你是这么发起请求的:
// 新API的权限请求 ActivityResultLauncher<String[]> locationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> { // 这里才是正确处理权限结果的地方 boolean hasFineLocation = result.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false); boolean hasCoarseLocation = result.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false); if (hasFineLocation || hasCoarseLocation) { // 权限已授予,初始化MyLocation图层 } }); // 发起请求 locationPermissionLauncher.launch(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION });
那你之前写的onRequestPermissionsResult完全不会被调用,这时候在旧回调里判断grantResults为空就会弹出错误Toast,但实际上权限已经通过新API的回调处理了,所以你能正常使用图层。
解决办法:把权限结果的处理逻辑全部移到新API的ActivityResultCallback回调里,删掉旧的onRequestPermissionsResult方法,或者至少不要在旧方法里做错误提示。
2. 旧API回调未调用super方法
如果你还是用的旧版requestPermissions方法发起请求,比如:
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_CODE);
那一定要确保在重写onRequestPermissionsResult时,先调用父类的方法:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { // 必须先调用super,确保AppCompatActivity的内部逻辑正常执行 super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_CODE) { if (grantResults.length > 0) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限授予成功 } } else { // 这里的Toast别乱弹,先确认是不是真的没结果 Toast.makeText(this, "grantArray为空", Toast.LENGTH_SHORT).show(); } } }
虽然不调用super不一定直接导致grantResults为空,但某些系统版本或AppCompatActivity的内部处理可能会受影响,加上更稳妥。
3. RequestCode重复冲突
检查一下你的权限请求码(比如LOCATION_PERMISSION_CODE)是不是和其他Activity请求、权限请求的code重复了?如果有多个请求用了同一个code,可能会导致回调时拿到错误的结果,甚至空数组。确保每个权限请求的code是唯一的数值。
最后再提醒一下:既然你已经能正常使用MyLocation图层,说明权限确实已经被系统授予了,问题就出在你的回调逻辑没有正确捕获到这个结果,重点排查是不是混用了新旧API的问题!
内容的提问来源于stack exchange,提问作者Luigi Caradonna

