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