React Native用react-native-permissions Android端不显示定位权限弹窗问题
问题排查及修复方案
1. 优先排查模拟器状态问题
- 进入模拟器设置→应用→找到你的App→权限→将定位权限改成「拒绝」或者「询问」,如果之前已经选了「拒绝且不再询问」,后续调用权限申请接口不会再弹窗,只会直接返回
BLOCKED状态,你的代码中仅处理了DENIED状态,自然不会触发弹窗。 - 直接卸载模拟器上已安装的旧版App,重新编译运行,排除历史权限配置干扰。
2. 补全react-native-permissions的Android端配置
你目前仅添加了AndroidManifest的权限声明,还需要补全构建配置,确保依赖包包含定位权限的处理逻辑:
- 在
android/app/build.gradle的dependencies块中添加如下配置:
dependencies { // 保留原有其他依赖 implementation 'com.google.android.gms:play-services-location:21.0.1' }
- 在
android/build.gradle的ext块中新增权限引入配置:
ext { // 保留原有其他配置 reactNativePermissions = [ include: ['ACCESS_FINE_LOCATION', 'ACCESS_COARSE_LOCATION'] ] }
配置完成后清理构建缓存重新编译:
cd android && ./gradlew clean && cd .. && npx react-native run-android
3. 业务代码逻辑优化
3.1 兼容Android多版本权限规则
Android 12(API 31)及以上版本,申请精确定位需要同时请求ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION,且需要新增BLOCKED状态的处理逻辑,修改后的权限判断代码如下:
import { checkMultiple, requestMultiple, PERMISSIONS, RESULTS } from 'react-native-permissions'; // ...其他代码不变 const handleLocationPermission = async () => { if (Platform.OS === 'ios') { const permissionCheck = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE); if (permissionCheck === RESULTS.DENIED) { const permissionRequest = await request( PERMISSIONS.IOS.LOCATION_WHEN_IN_USE, ); return permissionRequest === RESULTS.GRANTED } return permissionCheck === RESULTS.GRANTED } if (Platform.OS === 'android') { const permissions = Platform.Version >= 31 ? [PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION, PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION] : [PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION] const permissionCheck = await checkMultiple(permissions); const allDenied = Object.values(permissionCheck).every(status => status === RESULTS.DENIED) const allGranted = Object.values(permissionCheck).every(status => status === RESULTS.GRANTED) if (allDenied) { const permissionResult = await requestMultiple(permissions) return Object.values(permissionResult).every(status => status === RESULTS.GRANTED) } if (Object.values(permissionCheck).some(status => status === RESULTS.BLOCKED)) { console.warn('权限被永久拒绝,请前往应用设置开启定位权限') } return allGranted } return false };
3.2 调整定位调用时机
你当前的定位获取逻辑和权限申请逻辑是并行执行的,可能出现权限还没申请完成就调用了定位接口,需要将定位逻辑放到权限申请成功之后执行,修改useEffect如下:
useEffect(() => { const init = async () => { const hasPermission = await handleLocationPermission(); if (hasPermission) { Geolocation.getCurrentPosition( (position) => { const { latitude, longitude } = position.coords; setLocation({ latitude, longitude }); }, (error) => { console.log(error.code, error.message); }, { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }, ); } } init(); }, []);
4. 其他注意事项
- 若你的Android模拟器系统版本为Android 13及以上,需确保
react-native-permissions版本在3.6.0以上,否则会存在兼容性问题 - 可以在权限申请的各个节点打印权限状态返回值,可快速定位是状态判断问题还是配置问题
内容的提问来源于stack exchange,提问作者user12494839
相关产品推荐
相关产品推荐

