使用背景
在国内应用市场审核标准更新之后,部分厂商需要在用户授权之前添加权限说明
这里先附上uniapp官网关于国内应用市场相关注意事项文档
代码实现
话不多说,直接上代码, 对于ios系统,这里不做处理
/**
* 是否为ios
* @returns {Promise<unknown>}
*/
const checkIsIos = async () => {
return new Promise((resolve => {
uni.getSystemInfo({
success: function (res) {
resolve(res.osName === "ios")
}
});
}))
}
const contentData = {
['android.permission.BLUETOOTH_CONNECT']: {
title: "蓝牙权限:",
describe: "授权应用程序连接到蓝牙设备,实现数据传输或其他蓝牙功能。\n"
},
['android.permission.BLUETOOTH_ADMIN']: {
title: "蓝牙权限:",
describe: "授权应用程序连接到蓝牙设备,实现数据传输或其他蓝牙功能。\n"
},
['android.permission.ACCESS_FINE_LOCATION']: {
title: "定位权限:",
describe: "获取您的当前位置信息,用于提供定位服务。\n"
},
['android.permission.ACCESS_COARSE_LOCATION']: {
title: "定位权限:",
describe: "获取您的当前位置信息,用于提供定位服务。\n"
},
["android.permission.READ_EXTERNAL_STORAGE"]: {
title: "存储权限:",
describe: "允许访问您的存储空间,用于发送或保存照片、文件和日志。\n"
},
["android.permission.CAMERA"]: {
title: "摄像头权限:",
describe: "用于访问您的设备摄像头,以便拍摄照片,提供实时图像功能。 \n"
},
["android.permission.CALL_PHONE"]: {
title: "拨打电话权限:",
describe: "用于应用程序唤起手机电话,拨打电话。\n"
},
}
export default class authorizeUtils {
/**
* 授权前告知用户使用意图
* @param content
* @returns
*/
static checkAuth = async (authorize, callBack) => {
// ios端在manifest.json配置权限使用说明,以下权限判断仅在安卓端可用
let isIos = await checkIsIos()
if (isIos) callBack()
let desc = ''
let compat = plus.android.importClass('androidx.core.content.ContextCompat')
let context = plus.android.runtimeMainActivity()
let authFlag = true
let res = compat.checkSelfPermission(context, authorize)
if (res !== 0) {
authFlag = false
desc = contentData[authorize].title + contentData[authorize].describe
}
if (!authFlag) {
uni.showModal({
title: '获取权限说明',
content: desc,
success: (res) => {
console.log(res)
if (!!res.confirm) {
plus.android.requestPermissions([authorize], (res) => {
if (res.granted.length > 0) {
callBack()
} else {
this.showManualAuth(authorize)
}
})
}
},
fail: () => {
}
})
} else {
callBack()
}
}
/**
* 用户拒绝授权提示手动授权
* @param authorize
* @returns {Promise<boolean>}
*/
static showManualAuth = async (authorize) => {
let isIos = await checkIsIos()
if (isIos) return true
const contentData = {
['android.permission.BLUETOOTH']: {
title: "蓝牙权限:",
describe: "授权应用程序连接到蓝牙设备,实现数据传输或其他蓝牙功能。\n"
},
['android.permission.BLUETOOTH_CONNECT']: {
title: "蓝牙权限:",
describe: "授权应用程序连接到蓝牙设备,实现数据传输或其他蓝牙功能。\n"
},
['android.permission.BLUETOOTH_ADMIN']: {
title: "蓝牙权限:",
describe: "授权应用程序连接到蓝牙设备,实现数据传输或其他蓝牙功能。\n"
},
['android.permission.ACCESS_FINE_LOCATION']: {
title: "定位权限:",
describe: "获取您的当前位置信息,用于提供定位服务。\n"
},
['android.permission.ACCESS_COARSE_LOCATION']: {
title: "定位权限:",
describe: "获取您的当前位置信息,用于提供定位服务。\n"
},
["android.permission.READ_EXTERNAL_STORAGE"]: {
title: "存储权限:",
describe: "允许访问您的存储空间,用于发送或保存照片、文件和日志。\n"
},
["android.permission.CAMERA"]: {
title: "摄像头权限:",
describe: "用于访问您的设备摄像头,以便拍摄照片,提供实时图像功能。 \n"
},
["android.permission.CALL_PHONE"]: {
title: "拨打电话权限:",
describe: "用于应用程序唤起手机电话,拨打电话。\n"
},
}
uni.showModal({
title: '提示',
content: contentData[authorize].title + contentData[authorize].describe,
confirmText: "去设置",
success: (res) => {
if (res.confirm) {
uni.openAppAuthorizeSetting({
success(res) {
console.log(res);
}
});
}
if (res.cancel) {
console.log('用户点击取消');
}
}
});
}
}
使用方式
在需要唤起授权的实践中直接调用authorizeUtils.checkAuth(permissonCode, callback)
,permissionCode为andriod权限code, callback为授权成功之后的回调函数
举例如下:
<template>
<view class="uni-btn-v">
<button @click="makeCall">拨打电话</button>
</view>
</template>
<script setup>
import authorizeUtils from "@/utils/authorizeUtils.ts"
const makeCall = () => {
authorizeUtils.checkAuth('android.permission.CALL_PHONE', () => {
// ...这里添加拨打电话的逻辑
})
}
</script>