React Native 做相机、定位、相册、推送权限管理,推荐不要自己封装 Native 权限,而是统一使用:
react-native-permissions
它统一封装 iOS / Android 权限申请、检查、跳转设置等流程。(NPM)
整体流程:
用户操作 ↓ 业务功能触发 ↓ check权限 ↓ 未授权 → request权限 ↓ granted → 执行业务 denied → 提示原因 blocked → 引导打开系统设置1. 安装
npm install react-native-permissions cd ios pod install(NPM)
一、相机权限 Camera
Android
android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>iOS
Info.plist
<key>NSCameraUsageDescription</key> <string>需要使用相机拍摄照片</string>RN代码
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions'; async function requestCamera(){ const result = await request( PERMISSIONS.IOS.CAMERA ); if(result === RESULTS.GRANTED){ console.log("可以使用相机"); } if(result === RESULTS.BLOCKED){ console.log("去设置开启"); } }Android:
request( PERMISSIONS.ANDROID.CAMERA )二、定位权限 Location
Android
Manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>iOS
Info.plist:
<key>NSLocationWhenInUseUsageDescription</key> <string>用于获取当前位置</string>如果后台定位:
<key>NSLocationAlwaysUsageDescription</key> <string>后台需要持续定位</string>代码:
import {PERMISSIONS} from 'react-native-permissions'; async function requestLocation(){ const res = await request( PERMISSIONS.IOS.LOCATION_WHEN_IN_USE ) if(res === RESULTS.GRANTED){ console.log("定位成功") } }Android:
request( PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION )三、相册权限 Photo Library
Android 13+
需要:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>Android 12:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>iOS
Info.plist:
<key>NSPhotoLibraryUsageDescription</key> <string>用于选择图片</string>代码:
request( PERMISSIONS.IOS.PHOTO_LIBRARY )Android:
request( PERMISSIONS.ANDROID.READ_MEDIA_IMAGES )四、推送权限 Notification
推送比较特殊。
需要:
系统通知权限
APNs / FCM 注册
推送 Token
推荐:
@react-native-firebase/messaging
iOS
请求通知:
import { requestNotifications } from 'react-native-permissions'; async function notificationPermission(){ const result = await requestNotifications([ 'alert', 'sound', 'badge' ]); console.log(result.status) }(NPM)
Android 13+
Manifest:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>请求:
request( PERMISSIONS.ANDROID.POST_NOTIFICATIONS )五、统一权限管理封装
实际项目一般这样写:
src └── permissions ├── camera.js ├── location.js ├── photo.js └── notification.js例如:
permission.js
import { request, RESULTS } from 'react-native-permissions'; export async function checkPermission(permission){ const result = await request(permission); switch(result){ case RESULTS.GRANTED: return true; case RESULTS.BLOCKED: //打开设置 return false; default: return false; } }业务调用:
const ok = await checkPermission( PERMISSIONS.IOS.CAMERA ) if(ok){ openCamera() }六、推荐权限申请时机
不要 App 启动一次申请全部:
❌
打开APP 请求: 相机 定位 相册 通知 用户疯狂点拒绝体验很差。
推荐:
相机
用户点击:
扫一扫 拍照上传再请求。
定位
进入地图页面:
附近的人 附近商家 导航请求。
相册
点击:
上传图片请求。
通知
登录完成 / 引导页:
开启通知,及时收到消息请求。
七、生产级权限状态处理
建议封装:
| 状态 | 处理 |
|---|---|
| GRANTED | 直接使用 |
| DENIED | 再次request |
| BLOCKED | 弹窗,引导系统设置 |
| LIMITED(iOS) | 提示用户选择更多权限 |
| UNAVAILABLE | 设备不支持 |
react-native-permissions本身提供这些状态。(NPM)
八、常见 RN APP 权限架构
类似微信:
App启动 | |-- 初始化SDK | |-- 登录 | |-- 用户进入功能 | +-- 扫一扫 | | | Camera Permission | +-- 发朋友圈 | | | Photo Permission | +-- 附近 | | | Location Permission | +-- 消息提醒 | Notification Permission这样通过率和用户体验最好。
如果是 RN 新架构(Fabric + TurboModule)项目,权限层建议独立成 Native Module Service,不要散落在页面组件里。