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

React Native用react-native-permissions Android端不显示定位权限弹窗问题

问题排查及修复方案

1. 优先排查模拟器状态问题

  • 进入模拟器设置→应用→找到你的App→权限→将定位权限改成「拒绝」或者「询问」,如果之前已经选了「拒绝且不再询问」,后续调用权限申请接口不会再弹窗,只会直接返回BLOCKED状态,你的代码中仅处理了DENIED状态,自然不会触发弹窗。
  • 直接卸载模拟器上已安装的旧版App,重新编译运行,排除历史权限配置干扰。

2. 补全react-native-permissions的Android端配置

你目前仅添加了AndroidManifest的权限声明,还需要补全构建配置,确保依赖包包含定位权限的处理逻辑:

  1. 在android/app/build.gradle的dependencies块中添加如下配置:
dependencies {
  // 保留原有其他依赖
  implementation 'com.google.android.gms:play-services-location:21.0.1'
}
  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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:06:03