uniapp_05_权限检测和跳转到设置
关于 uniapp 权限申请和跳转系统页面
- 测试环境
- 查询权限
- 跳转到应用详情
- 跳转到系统设置
- 参考
测试环境
- Android 测试环境1:雷电模拟器 HUAWEI LIO-AN00 系统版本 9
- Android 测试环境2:1+ace2 系统版本 13
查询权限
uni.authorize 获取权限只支持微信小程序不支持app,只能用 Native.js 来实现
-
android 查询权限
- 安卓
太多不想写
- uniapp
plus.android.requestPermissions(permissions, successCb, errorCB)
- permissions: 需要查询的权限数组 ps 此文中只封装了一次查询一个权限,需要的自己改
- successCb:成功回调 有三个参数
- granted - Array[String]字符串数组,已获取权限列表
- deniedPresent - Array[String]字符串数据,已拒绝(临时)的权限列表
- deniedAlways - Array[String]字符串数据,永久拒绝的权限列表
- errorCB: 失败回调
// permissionID:传入对应的权限常量 // 1: 授权 -1:永久拒绝 0:暂时拒绝 requestAndroidPermission(permissionID) { return new Promise((resolve, reject)=>{ plus.android.requestPermissions( [permissionID], (res)=>{ const { granted, deniedPresent, deniedAlways } = res; if(granted.length) resolve(1); if(deniedPresent.length) resolve(0); if(deniedAlways.length) resolve(-1); }, (err)=>{ resolve({...err})} ) }) }
- 安卓
-
android 只验证权限
-
安卓
网上讲验证的 api 是 android.support.v4.content.ContextCompat 下面的 checkSelfPermission 方法,但是我导入后,使用时报错提示没有这个方法。查找文档之后发现在 android.core.app.ActivityCompat 下存在 checkSelfPermission 方法但是导入后使用,依旧报错。仔细看包之后发现 content,ActivityCompat 有些方法好像被 Native.js 整合进入 plus.android.runtimeMainActivity() 里面了,这样的话等下我想下我以前是不是导入了很多不需要导入的包emmm
-
uniapp
plus.android.runtimeMainActivity().checkSelfPermission('权限')
返回: 0: 无授权 1: 以授权// 验证是否存在定位权限 const main = plus.android.runtimeMainActivity(); main.checkSelfPermission('android.permission.ACCESS_FINE_LOCATION')
-
-
ios 查询权限
看最后的代码,很烦要导入不同的包
跳转到应用详情
-
android 跳转
setData : 传入的是uri,用于数据的过滤。setData可以被系统用来寻找匹配目标组件。
putExtra: 只是用来设定各种不同类型的附加数据。不被系统用来寻找匹配目标组件。
直接跳转应用详情里的权限页需要适配不同品牌的手机 (用雷电模拟器试了华为的发现没用)
- 安卓
Intent intent = new Intent(); intent.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + this.getPackageName())); startActivity(intent);
- uniapp
// 跳转到应用详情 const main = plus.android.runtimeMainActivity(); const Intent = plus.android.newObject("android.content.Intent"); // const Settings = plus.android.importClass("android.provider.Settings"); const pkName = main.getPackageName(); const uri = plus.android.invoke("android.net.Uri", 'fromParts', 'package', pkName, null); // plus.android.invoke(Intent, 'setAction', Settings.ACTION_APPLICATION_DETAILS_SETTINGS); // 直接用 android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTING 不行 我也不知道为啥 plus.android.invoke(Intent, 'setAction', 'android.settings.APPLICATION_DETAILS_SETTINGS'); plus.android.invoke(Intent, 'setData', uri); plus.android.invoke(main, 'startActivity', Intent); // 跳转到应用详情对应权限设置 // 华为 (不生效) const main = plus.android.runtimeMainActivity(); const Intent = plus.android.importClass('android.content.Intent'); let _intent = new Intent(); _intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); const pkName = main.getPackageName(); _intent.putExtra("packageName", pkName); const ComponentName = plus.android.importClass('android.content.ComponentName'); const _comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity"); _intent.setComponent(_comp); main.startActivity(_intent);
- 安卓
-
IOS 跳转
// 跳转应用详情 const app = plus.ios.invoke('UIApplication', 'sharedApplication'); const setting = plus.ios.invoke('NSURL', 'URLWithString:', 'app-settings:'); plus.ios.invoke(app, 'openURL:', setting); plus.ios.deleteObject(setting); plus.ios.deleteObject(app);
跳转到系统设置
-
android 跳转系统设置页面
const main = plus.android.runtimeMainActivity(), Settings = plus.android.importClass("android.provider.Settings"); const Intent = plus.android.newObject('android.content.Intent', Settings.ACTION_SETTINGS); main.startActivity(Intent);
-
android 跳转具体服务设置页面
// 跳转到 打开系统定位服务页面 const main = plus.android.runtimeMainActivity(), Intent = plus.android.importClass('android.content.Intent'); const Settings = plus.android.importClass('android.provider.Settings'); // let _intent = new Intent('android.settings.LOCATION_SOURCE_SETTINGS'); // 也可不需要Settings 直接这么写 let _intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); main.startActivity(_intent); // 打开系统设置GPS服务页面
-
IOS 跳转系统设置页面
看跳转应用
// 权限js
// #ifdef APP
// 判断推送权限是否开启
function judgeIosPermissionPush() {
var result = false;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
if (enabledTypes == 0) {
} else {
result = true;
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
} else {
result = true;
}
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
// 判断定位权限是否开启
function judgeIosPermissionLocation() {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var status = cllocationManger.authorizationStatus();
if (status == 0 || status == 3) {
result = true;
} else {
if (status == 2) {
// gotoAppSetting('我们需要访问您的位置,方便更加迅速的给您解决问题')
}
}
plus.ios.deleteObject(cllocationManger);
return result;
}
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
var result = false;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var permissionStatus = avaudio.recordPermission();
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
} else {
result = true;
}
plus.ios.deleteObject(avaudiosession);
return result;
}
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
var result = false;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
if (authStatus == 0 || authStatus == 3) {
result = true
} else {
if (authStatus == 2) {
// gotoAppSetting('请先允许使用相机权限')
}
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
// 判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
var result = false;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
if (authStatus == 0 || authStatus == 3) {
result = true;
} else {
if (authStatus == 2) {
// gotoAppSetting('请先允许访问相册权限')
}
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
var result = false;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus == 0 || cnAuthStatus == 3) {
result = true;
} else {
}
plus.ios.deleteObject(CNContactStore);
return result;
}
// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 0 || ekAuthStatus == 3) {
result = true;
} else {
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 0 || ekAuthStatus == 3) {
result = true;
} else {
}
plus.ios.deleteObject(EKEventStore);
return result;
}
class Permission {
#_permissonList: {
'contact': { // 通讯录
'android': 'android.permission.WRITE_CONTACTS',
'ios': 'CNContactStore'
},
'calendar': { // 日历-写
'android': 'android.permission.WRITE_CALENDAR',
'ios': 'CNContactStore'
},
'location': { // 定位
'android': 'android.permission.ACCESS_FINE_LOCATION',
'ios': 'CLLocationManager'
},
'sms': { // 发-信息
'android': 'android.permission.SEND_SMS',
'ios': ''
},
'storage': { // 外部存储和相册-写
'android': 'android.permission.WRITE_EXTERNAL_STORAGE',
'ios': 'PHPhotoLibrary'
},
'camera': { // 摄像头
'android': 'android.permission.CAMERA',
'ios': 'AVCaptureDevice'
},
'record': { // 麦克风
'android': 'android.permission.RECORD_AUDIO',
'ios': 'AVAudioSession'
},
},
#_androidAppActionList: { // 跳转应用的
'push': 'android.settings.APP_NOTIFICATION_SETTINGS', // app的通知权限开关页面
},
#_systemActionList: { // 跳转系统设置页面
'location': { // gps开关页面
'android': 'android.settings.LOCATION_SOURCE_SETTINGS',
'ios': ''
}
},
constructor () {
// 判断手机系统和系统版本
let os = plus.os.name; // 系统名称
this.isIos = os == 'iOS'; // 是否是ios系统
if(this.isIos) {
this.version = plus.os.version; // 版本
} else {
const Build = plus.android.importClass("android.os.Build");
this.version = Build?.VERSION?.SDK_INT ?? 0;
}
}
/**
* @method requestAndroidPermission
* @param {String} permissionID 安卓的权限
* @description android 动态申请权限
* @return {Number | Object} -1: 拒绝权限(永久) 0: 拒绝权限(临时)1:授权 || { code:'错误码', message:"错误描述" }
*/
requestAndroidPermission (permissionID) {
return new Promise((resolve, reject)=>{
// TODO 需要添加验证权限的函数
// FIXME ContextCompat.checkSelfPermission() 可以验证是否存某权限
plus.android.requestPermissions(
[permissionID],
(res)=>{
const { granted, deniedPresent, deniedAlways } = res;
if(granted.length) resolve(1); // 以获取到权限
if(deniedPresent.length) resolve(0); // 已拒绝权限(临时)
if(deniedAlways.length) resolve(-1); // 已拒绝权限(永久)
},
(err)=>{
// message: 错误信息描述 code : 错误编码
resolve({...err});
}
)
})
}
/**
* @method verifyNotification
* @return {Boolean} true: 存在权限 false: 无权限
* @description 获取**app**推送授权状态
*/
verifyNotification() {
if (this.isIos) {
let types = 0;
const app = plus.ios.invoke('UIApplication', 'sharedApplication');
const settings = plus.ios.invoke(app, 'currentUserNotificationSettings');
if(settings) {
types = settings.plusGetAttribute('types');
} else {
types = plus.ios.invoke(app, 'enabledRemoteNotificationTypes');
}
plus.ios.deleteObject(settings);
plus.ios.deleteObject(app);
return types != 0;
} else {
const main = plus.android.runtimeMainActivity();
let NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");
if (NotificationManagerCompat == null) {
NotificationManagerCompat = plus.android.importClass("androidx.core.app.NotificationManagerCompat");
}
const areNotificationsEnabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
return areNotificationsEnabled;
}
},
/**
* @method verifyPermission
* @param {String} name 权限名称
* @description 验证是否存在授权
* @return {boolean} false: 拒绝 true:授权
*/
verifyPermission (name='') {
if(this.isIos) {
// 需要单独处理 去调用上面方法
} else {
const main = plus.android.runtimeMainActivity();
const state = main.checkSelfPermission(this.#_permissonList[name]['android']);
return state == 1;
}
}
/**
* @method jumpAppDataPage
* @description 跳转到**应用**的信息页面
*/
jumpAppInfoPage () {
if (this.isIos) {
const app = plus.ios.invoke('UIApplication', 'sharedApplication');
const setting = plus.ios.invoke('NSURL', 'URLWithString:', 'app-settings:');
plus.ios.invoke(app, 'openURL:', setting);
plus.ios.deleteObject(setting);
plus.ios.deleteObject(app);
} else {
const main = plus.android.runtimeMainActivity();
const Intent = plus.android.newObject("android.content.Intent");
// const Settings = plus.android.importClass("android.provider.Settings");
const uri = plus.android.invoke("android.net.Uri", 'fromParts', 'package', main.getPackageName(), null);
// plus.android.invoke(Intent, 'setAction', Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
plus.android.invoke(Intent, 'setAction', `android.settings.APPLICATION_DETAILS_SETTINGS`);
plus.android.invoke(Intent, 'setData', uri);
plus.android.invoke(main, 'startActivity', Intent);
}
}
/**
* @method JumpAppPermissionPage
* @description 跳转到**应用**的授权开关页面 (ps: 这里也可以用来到设置页面啥的毕竟核心代码一样,但是懒得改了 )
*/
JumpAppPermissionPage (action='push') {
if(this.isIos) {
this.jumpAppInfoPage();
} else {
const main = plus.android.runtimeMainActivity();
const pkName = main.getPackageName();
const uid = main.getApplicationInfo().plusGetAttribute("uid");
const Intent = plus.android.newObject('android.content.Intent', this.#_androidActionList[action]);
if(this.version >= 26) { // 8.0
Intent.putExtra('android.provider.extra.APP_PACKAGE', pkName);
Intent.putExtra('android.provider.extra.CHANNEL_ID', uid);
main.startActivity(Intent);
} else if(this.version >= 21) { // 5.0-7.1
Intent.putExtra("app_package", pkName);
Intent.putExtra("app_uid", uid);
main.startActivity(Intent);
} else {
this.jumpAppInfoPage();
}
}
},
/**
* @method verifySystemLocationServe
* @description 验证**系统**定位服务是否开启
*/
verifySystemLocationServe () {
if (this.isIos) {
// TODO 需要更具不同服务进行封装
// 验证定位服务是否开启的
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var result = cllocationManger.locationServicesEnabled();
plus.ios.deleteObject(cllocationManger);
return result;
} else {
const main = plus.android.runtimeMainActivity(),
context = plus.android.importClass("android.content.Context"),
locationManager = plus.android.importClass("android.location.LocationManager");
const mainSvr = main.getSystemService(context.LOCATION_SERVICE);
return mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER)
}
},
/**
* @method jumpSystemAppointPage
* @description 跳转到指定的**系统**设置页面 (使用之前先确定 页面是可以直接跳转的)
*/
jumpSystemAppointPage (action="location") {
if (this.isIos) {
} else {
const main = plus.android.runtimeMainActivity();
const Intent = plus.android.newObject('android.content.Intent', this.#_systemActionList[action]['android']);
main.startActivity(Intent); // 打开系统设置GPS服务页面
}
}
/**
* @method jumpSystemPage
* @description 跳转到系统设置页面
*/
jumpSystemPage () {
if (this.isIos) {
this.jumpAppInfoPage();
} else {
const main = plus.android.runtimeMainActivity();
// const Settings = plus.android.importClass("android.provider.Settings");
// const Intent = plus.android.newObject('android.content.Intent', Settings.ACTION_SETTINGS);
const Intent = plus.android.newObject('android.content.Intent',`android.settings.SETTINGS`);
main.startActivity(Intent);
}
}
}
// #endif