文章目录
- 两端获取权限的区别
- Android端
- iOS
- iOS 桥接文件
- 使用
RN工程做个权限列表开关
相机
相册
日历
定位
…
两端获取权限的区别
android 调用申请权限,系统会呈现两个还是三个系统弹窗, 直到你同意或拒绝后,选择不在提示,
iOS端,调用申请权限,系统弹窗仅会弹出一次, 该次就决定了你的权限策略, 此后再调用申请权限
API 均无系统弹窗了
区别就是:
android,会一直弹出, 直到你同意或不再提示
iOS仅弹出一次,你此次必须决定授权与否, 此次过后不再弹窗,(除非重装)
所以,针对表现形式不同,逻辑也要做不同处理 (如果要做到双端一致的话)
Android端,选择不再提示后, 帮助用户跳转系统设置,交给用户自己处理
iOS端, 申请过一次后, 下次用户再进行设置 ,就应该帮用户直接跳转系统设置
Android端
PermissionsAndroid
就足够了
[PermissionsAndroid文档]
(https://reactnative.cn/docs/0.68/permissionsandroid)
android端对各种权限的状态获取 / 权限申请, 由于有PermissionsAndroid
的关系, 可以直接在RN端处理开发
贴一下RN端处理代码, 仅关注 !isIOS
逻辑分支(即Android端)内的即可, else
分支内为iOS桥接代码,后面再贴出来.
/*************************** 1 ***************************/
/**
* 检查相册权限状态
*/
static checkReadWPermission() {
return new Promise(async (resolv, reject) => {
if (!isIOS) {
try {
let check_r = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE)
let check_w = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE)
if (check_r || check_w) {
resolv()
} else {
reject()
}
} catch (e) {
reject()
}
} else {
let res = NativeModules.GeneralModule.checkPhotoAlbumState();
if (res === "yes") {
resolv()
} else {
reject()
}
}
})
}
/**
* 申请相册权限(获取读写权限)
*/
static requestReadWPermission() {
return new Promise((resolve, reject) => {
if (!isIOS) {
PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
]).then(granted => {
if (
granted["android.permission.READ_EXTERNAL_STORAGE"] === PermissionsAndroid.RESULTS.GRANTED ||
granted["android.permission.WRITE_EXTERNAL_STORAGE"] === PermissionsAndroid.RESULTS.GRANTED
) {
rlog('你已获取了相册权限');
resolve("yes");
}
if (
granted["android.permission.READ_EXTERNAL_STORAGE"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
granted["android.permission.WRITE_EXTERNAL_STORAGE"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
) {
rlog('不再提示相册权限');
resolve("naver");
} else {
rlog('获取相册权限失败');
reject();
}
})
.catch(err => {
reject();
});
}
// ios
else {
let res = NativeModules.GeneralModule.getPhotoAlbumState();
if (res === 'yes') {
rlog('你已获取了相册权限');
resolve()
} else {
rlog('获取相册权限失败');
reject()
}
}
});
}
/**
* 检查相机权限状态
*/
static checkCameraPermission() {
return new Promise(async (resolv, reject) => {
if (!isIOS) {
try {
let check = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.CAMERA);
check ? resolv() : reject()
} catch (e) {
reject()
}
} else {
let res = NativeModules.GeneralModule.checkCameraState();
if (res === "yes") {
resolv()
} else {
reject()
}
}
})
}
/**
* 申请相机权限
* @returns {Promise<R>}
*/
static requestCameraPermisson() {
return new Promise((resolve, reject) => {
if (!isIOS) {
PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,
]).then(granted => {
if (
granted["android.permission.CAMERA"] === PermissionsAndroid.RESULTS.GRANTED
) {
rlog('你已获取了相机权限');
resolve("yes");
}
if (
granted["android.permission.CAMERA"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
) {
rlog("不再提示相机权限")
resolve("naver")
} else {
rlog('获取相机权限失败');
reject();
}
})
.catch(err => {
reject();
});
}
// ios
else {
let res = NativeModules.GeneralModule.getCameraState();
if (res === 'yes') {
rlog('你已获取了相机权限');
resolve()
} else {
rlog('获取相机权限失败');
reject()
}
}
});
}
/**
* 检查日历权限状态
*/
static checkCalendarPermission() {
return new Promise(async (resolv, reject) => {
if (!isIOS) {
try {
let check_r = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_CALENDAR)
let check_w = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_CALENDAR)
if (check_w || check_r) {
resolv()
} else {
reject()
}
} catch (e) {
reject()
}
} else {
let res = NativeModules.GeneralModule.checkCalendarState();
if (res === "yes") {
resolv()
} else {
reject()
}
}
})
}
/**
* 申请日历权限
*/
static requestCalendarPermission() {
return new Promise((resolve, reject) => {
if (!isIOS) {
PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.READ_CALENDAR,
PermissionsAndroid.PERMISSIONS.WRITE_CALENDAR,
]).then((granted) => {
if (
granted["android.permission.READ_CALENDAR"] === PermissionsAndroid.RESULTS.GRANTED ||
granted["android.permission.WRITE_CALENDAR"] === PermissionsAndroid.RESULTS.GRANTED
) {
rlog('你已获取了日历权限');
resolve("yes")
}
if (
granted["android.permission.READ_CALENDAR"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
granted["android.permission.WRITE_CALENDAR"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
) {
rlog('不再提示日历权限');
resolve("naver")
} else {
rlog('获取日历权限失败');
reject()
}
}).catch(err => {
reject()
})
}
// ios
else {
let res = NativeModules.GeneralModule.getCalendarState();
if (res === 'yes') {
rlog('你已获取了日历权限');
resolve()
} else {
rlog('获取日历权限失败');
reject()
}
}
});
}
/**
* 检查定位权限状态
*/
static checkLoacationPermission() {
return new Promise(async (resolv, reject) => {
if (!isIOS) {
try {
let check_fine = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION)
let check_coarse = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION)
if (check_coarse || check_fine) {
resolv()
} else {
reject()
}
} catch (e) {
reject()
}
} else {
let res = NativeModules.GeneralModule.checkLocationState();
if (res === "yes") {
resolv()
} else {
reject()
}
}
})
}
/**
* 申请地理位置权限
*/
static requestloactionPermission() {
return new Promise((resolve, reject) => {
if (!isIOS) {
PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
]).then((granted) => {
if (
granted["android.permission.ACCESS_FINE_LOCATION"] === PermissionsAndroid.RESULTS.GRANTED ||
granted["android.permission.ACCESS_COARSE_LOCATION"] === PermissionsAndroid.RESULTS.GRANTED
) {
rlog('你已获取了定位权限');
resolve("yes")
}
if (
granted["android.permission.ACCESS_FINE_LOCATION"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
granted["android.permission.ACCESS_COARSE_LOCATION"] === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
) {
rlog("不再提示定位权限")
resolve("naver")
} else {
rlog('获取定位权限失败');
reject()
}
}).catch(err => {
reject()
})
}
// ios
else {
let res = NativeModules.GeneralModule.getLocationState();
if (res === 'yes') {
rlog('你已获取了定位权限');
resolve()
} else {
rlog('获取定位权限失败');
reject()
}
}
});
}
iOS
头文件:
#import <Photos/Photos.h>
#import <AVFoundation/AVCaptureDevice.h>
#import <AVFoundation/AVMediaFormat.h>
#import <Foundation/Foundation.h>
@import EventKit;
@import CoreLocation;
@import AVFoundation;
iOS原生类 支持的方法列表
+(NSString*)checkPhotoAlbumState;
+(NSString*)getPhotoAlbumState;
+(NSString*)checkCameraState;
+(NSString*)getCameraState;
+(NSString*)checkCalendarState;
+(NSString*)getCalendarState;
+(NSString*)checkLocationState;
+(NSString*)getLocationState;
iOS原生类 支持的方法列表的实现代码
/**
检查相册权限
*/
+(NSString*)checkPhotoAlbumState{
NSString * res = @"";
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
switch(status){
case PHAuthorizationStatusAuthorized:
res=@"yes";
break;
case PHAuthorizationStatusDenied:
res=@"no";
break;
case PHAuthorizationStatusNotDetermined:
res=@"no";
break;
case PHAuthorizationStatusRestricted:
res=@"yes";
break;
default:
break;
}
return res;
}
/**
申请相册
*/
+(NSString*)getPhotoAlbumState{
__block NSString * res = @"";
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
//----每次都会走进来
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
res = @"yes";
dispatch_semaphore_signal(sema);
}else{
res = @"no";
dispatch_semaphore_signal(sema);
}
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
return res;
}
/**
检查相机权限
*/
+(NSString*)checkCameraState{
NSString *res=@"";
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (status) {
case AVAuthorizationStatusAuthorized:
res=@"yes";
break;
case AVAuthorizationStatusDenied:
res=@"no";
break;
case AVAuthorizationStatusNotDetermined:
res=@"no";
break;
case AVAuthorizationStatusRestricted:
res=@"yes";
break;
default:
break;
}
return res;
}
/**
申请相机
*/
+(NSString*)getCameraState{
__block NSString* res = @"";
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
// 触发相册系统弹框
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
res= @"yes";
dispatch_semaphore_signal(sema);
}else{
res= @"no";
dispatch_semaphore_signal(sema);
}
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
return res;
}
/**
检查日历权限
*/
+(NSString*)checkCalendarState{
NSString *res = @"";
EKAuthorizationStatus status= [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status) {
case EKAuthorizationStatusAuthorized: //授权
res = @"yes";
break;
case EKAuthorizationStatusDenied: //拒绝
res = @"no";
break;
case EKAuthorizationStatusNotDetermined: // 不确定
res = @"no";
break;
case EKAuthorizationStatusRestricted: //限制
res = @"yes";
break;
default:
break;
}
return res;
}
/**
申请日历
*/
+(NSString*)getCalendarState{
__block NSString* res = @"";
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
EKEventStore *store = [[EKEventStore alloc]init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
res=@"yes";
dispatch_semaphore_signal(sema);
}else{
res=@"no";
dispatch_semaphore_signal(sema);
}
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
return res;
}
/**
检查定位权限
*/
+ (NSString *)checkLocationState{
NSString *res = @"";
//检查定位权限
CLAuthorizationStatus CLstatus = [CLLocationManager authorizationStatus];
switch (CLstatus) {
case kCLAuthorizationStatusAuthorizedAlways:
res=@"yes";
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
res=@"yes";
break;
case kCLAuthorizationStatusDenied:
res=@"no";
break;
case kCLAuthorizationStatusNotDetermined:
res=@"no";
break;
case kCLAuthorizationStatusRestricted:
res=@"yes";
break;
default:
break;
}
return res;
}
/**
申请定位
*/
+(NSString*)getLocationState{
__block NSString *res = @"";
BOOL isLocation = [CLLocationManager locationServicesEnabled];
if (isLocation) {
CLLocationManager *manager = [[CLLocationManager alloc] init];
[manager requestWhenInUseAuthorization];
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways) {
res = @"yes";
}
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
res = @"yes";
}
else{
res = @"no";
}
}else{
res = @"no";
}
return res;
}
iOS 桥接文件
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(checkPhotoAlbumState){
return [NativeUtils checkPhotoAlbumState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getPhotoAlbumState){
return [NativeUtils getPhotoAlbumState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(checkCameraState){
return [NativeUtils checkCameraState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getCameraState){
return [NativeUtils getCameraState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(checkCalendarState){
return [NativeUtils checkCalendarState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getCalendarState){
return [NativeUtils getCalendarState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(checkLocationState){
return [NativeUtils checkLocationState];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getLocationState){
return [NativeUtils getLocationState];
}
使用
直接调用一开始贴的JS代码即可