介绍
将申请 user_grant 权限的代码,进行封装
代码
创建目录
在 ets 创建目录 utils
创建文件
在 utils 目录下创建 RequestPermissions.ets 文件,内容如下:
import { abilityAccessCtrl, common, Permissions,bundleManager } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = "授权(RequestPermissions.ets)-----"
/**
* 所有要申请的权限
*/
const allPermissions: Array<Permissions> = [
// 'ohos.permission.LOCATION',
'ohos.permission.DISTRIBUTED_DATASYNC' // 申请麦克风权限
];
/**
* 所有要申请的权限,用户拒绝授权时的提示信息
*/
const allRejectedMessage: Array<string> = [
'需要使用分布式数据库权限'
]
let atManager: abilityAccessCtrl.AtManager;
/**
* 创建 AtManager 对象
*/
function createAtManager(){
if(!atManager){
console.debug(TAG,"amManager 为null,创建")
atManager = abilityAccessCtrl.createAtManager()
}else{
console.debug(TAG,"amManager 不为null,不用创建")
}
}
/**
* 校验权限
* @param permission
* @returns 返回 boolean 类型,true表示授权,false表示未授权
*/
export async function checkPermissionGrant(permission: Permissions): Promise<boolean> {
createAtManager();
let ret: boolean = false;
// 获取应用程序的accessTokenID
let tokenId: number = 0;
try {
const bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
const appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(TAG,`获取 bundle info 失败! Code is ${err.code}, message is ${err.message}`);
}
// 校验应用是否被授予权限
try {
const grantStatus = atManager.checkAccessTokenSync(tokenId, permission);
ret = ( grantStatus == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED )
} catch (err) {
ret = false
console.error(TAG,`校验权限失败!Code is ${err.code}, message is ${err.message}`);
}
return ret;
}
/**
* 一次申请所有的权限
* @param context
*/
export function requestAllPermissionsFromUserAndShow( uiContext: UIContext): void {
requestPermissionsFromUserAndShow(allPermissions,allRejectedMessage,uiContext);
}
/**
* 请求一个权限
* 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
* @param permission 申请的权限,Permissions类型
* @param rejectedMessage 用户拒绝授权的提示信息
* @param context
*/
export function requestPermissionFromUserAndShow(permission:Permissions,rejectedMessage:string, uiContext: UIContext): void {
requestPermissionsFromUserAndShow([permission],[rejectedMessage],uiContext);
}
/**
* 向用户申请多个权限
* 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
* @param permissions: Array<Permissions>,申请的权限
* @param rejectedMessage: Array<string>,对应权限,拒绝时的提示消息
* @param context
*/
export function requestPermissionsFromUserAndShow(permissions: Array<Permissions>,rejectedMessage: Array<string>, uiContext: UIContext): void {
if(!uiContext){
console.error(TAG, 'context不能为空');
return
}
createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(uiContext.getHostContext(), permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
console.log(TAG,`申请授权 ${permissions} 成功`);
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
// 显示Toast提示
try {
uiContext.getPromptAction().showToast({
message: rejectedMessage[i], // 提示文本
duration: 2000, // 显示时长(毫秒),默认1500ms,范围[1500, 3000]
bottom: 100 // 距离屏幕底部的距离(像素)
});
} catch (error) {
console.error(TAG,"promptAction.showToast() 报错!")
}
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(TAG,`申请权限失败, Code is ${err.code}, message is ${err.message}`);
})
}
/**
* 二次向用户申请授权
* 当应用通过requestPermissionsFromUser()拉起弹框请求用户授权时,用户拒绝授权。应用将无法再次通过requestPermissionsFromUser拉起弹框,需要用户在系统应用“设置”的界面中,手动授予权限。
* @param context 上下文
* @param permission 权限
* @returns 返回true,表示申请成功;false表示失败
*/
export async function requestPermissionOnSetting(permission: Permissions,context: Context): Promise<boolean>{
createAtManager()
try {
const datas = await atManager.requestPermissionOnSetting(context, [permission])
console.info(TAG, JSON.stringify(datas));
return datas[0] == 0
}catch (err){
console.error(TAG , `二次申请授权失败!code:${err.code},message:${err.message}`);
}
return false;
}
使用
申请麦克风权限,步骤如下:
添加授权配置
添加代码,有两种方式:
在
UIAbility中向用户申请授权在UI中向用户申请授权
添加授权
修改 module.json5 配置文件,添加下面内容:
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_permission_reason",
"usedScene": {
"when": "inuse",
"abilities": ["EntryAbility"]
}
}
如图:
添加需要权限原因
在 \resources\base\element\string.json 添加申请权限原因:
{
"name": "microphone_permission_reason",
"value": "需要使用麦克风"
}
导包
import {requestAllPermissionsFromUserAndShow,requestPermissionFromUserAndShow,checkPermissionGrant,requestPermissionOnSetting} from '../utils/RequestPermissions'
第一次启动申请权限
第一次启动申请权限,在 EntryAbility.ets 中加上下面代码:
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
// Main window is created, set main page for this ability
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', async (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
// 第一次启动申请权限
const pg = 'ohos.permission.MICROPHONE'
const reason = '需要使用麦克风'
const cpg = await checkPermissionGrant(pg)
if(cpg){
console.log(TAG,` 检测授予 ${pg} 授权`)
}else{
// 申请所有权限
// requestAllPermissionsFromUser(getContext())
// 只分布式数据同步权限
try {
const uiContext = windowStage.getMainWindowSync().getUIContext()
requestPermissionFromUserAndShow(pg,reason,uiContext)
}catch (err) {
console.error(TAG,`getMainWindowSync() 报错!code:${err.code},message:${err.message}`)
}
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}
二次申请权限
第一次运行申请权限,如果拒绝,在首页中,二次申请权限
在 Index.ets 中,加上下面代码
async aboutToAppear(): Promise<void> {
const pg = 'ohos.permission.MICROPHONE'
const reason = '需要使用麦克风'
await LoginKVStoreUtils.init(this.getUIContext().getHostContext()!)
const cpg = await checkPermissionGrant(pg)
if(cpg){
console.log(TAG,` 检测授予 ${pg} 授权`)
}else{
// 二次申请
try {
const context = this.getUIContext().getHostContext()
if (context != null) {
const rpos = await requestPermissionOnSetting(pg, context)
if (!rpos) {
try {
this.getUIContext().getPromptAction().showToast({
message: reason, // 提示文本
duration: 2000, // 显示时长(毫秒),默认1500ms,范围[1500, 3000]
bottom: 100 // 距离屏幕底部的距离(像素)
});
} catch (error) {
console.error(TAG, "promptAction.showToast() 报错!")
}
}
}
}catch (err) {
console.error(TAG,`getMainWindow() 报错!code:${err.code},message:${err.message}`)
}
}
}
