鸿蒙 Next 应用权限管理
- 2025-06-23 北京
本文字数:4095 字
阅读完需:约 13 分钟
简介:
系统提供了一种允许应用访问系统资源(如:通讯录等)和系统能力(如:访问摄像头、麦克风等)的通用权限访问方式,来保护系统数据(包括用户个人数据)或功能,避免它们被不当或恶意使用。
授权方式:
system_grant(系统授权 指的是系统授权类型,如果在应用中申请了 system_grant 权限,那么系统会在用户安装应用时,自动把相应权限授予给应用。
user_grant(用户授权) 指的是用户授权类型,该类型权限不仅需要在安装包中申请权限,还需要在应用动态运行时,通过发送弹窗的方式请求用户授权。在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。
以下通过定位权限介绍一下需要用户授权的权限请求步骤:

1.在配置文件中声明权限,应用需要在 module.json5 配置文件的 requestPermissions 标签中声明权限
"requestPermissions": [
{'name': 'ohos.permission.INTERNET'},
{
"name" : "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:location_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when":"inuse"
}
},
{
"name" : "ohos.permission.LOCATION",
"reason": "$string:location_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when":"inuse"
}
}
]
2.在需要用到定位权限的时候,查询是否有该权限,使用 atManager.checkAccessToken 方法,返回-1 无权限,0 有权限
3.如果没有权限,使用 atManager.requestPermissionsFromUser 方法动态向用户申请权限,通过回调判断是否同意
4.如果用户拒绝了该权限,还可以调用 atManager.requestPermissionOnSetting 直接拉起权限设置弹框,引导用户授予权限
在 page 中调用:
import { location_permissions, requestLocation, requestPermissionOnSetting } from '../utils/RequestPermission'
import { common } from '@kit.AbilityKit'
import { showToast } from '../utils/ToastUtil'
@Entry
@ComponentV2
struct permission{
build() {
Column(){
Button('获取定位权限').onClick(()=>{
requestLocation(getContext(this) as common.UIAbilityContext).then((result)=>{
if (result) {
showToast('获取成功')
}else {
showToast('获取失败')
requestPermissionOnSetting(location_permissions,getContext(this) as common.UIAbilityContext).then((result)=>{
if (result) {
showToast('获取成功')
}else {
showToast('获取失败')
}
})
}
})
})
}
}
}
权限请求控制方法:
import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
//位置
const LOCATION:Permissions = 'ohos.permission.LOCATION'
const LOCATION_IN_BACKGROUND:Permissions = 'ohos.permission.LOCATION_IN_BACKGROUND'
const APPROXIMATELY_LOCATION:Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'
export const location_permissions: Array<permissions> = [LOCATION,APPROXIMATELY_LOCATION]
//相机
const CAMERA:Permissions = 'ohos.permission.CAMERA'
//麦克风
const MICROPHONE:Permissions = 'ohos.permission.MICROPHONE'
//通讯录
const READ_CONTACTS:Permissions = 'ohos.permission.READ_CONTACTS'
const WRITE_CONTACTS:Permissions = 'ohos.permission.WRITE_CONTACTS'
//日历
const READ_CALENDAR:Permissions = 'ohos.permission.READ_CALENDAR'
const WRITE_CALENDAR:Permissions = 'ohos.permission.WRITE_CALENDAR'
//运动数据
const ACTIVITY_MOTION:Permissions = 'ohos.permission.ACTIVITY_MOTION'
//身体传感器
const READ_HEALTH_DATA:Permissions = 'ohos.permission.READ_HEALTH_DATA'
//图片和视频
const WRITE_IMAGEVIDEO:Permissions = 'ohos.permission.WRITE_IMAGEVIDEO'
const READ_IMAGEVIDEO:Permissions = 'ohos.permission.READ_IMAGEVIDEO'
const MEDIA_LOCATION:Permissions = 'ohos.permission.MEDIA_LOCATION'
//音乐和音频
const WRITE_AUDIO:Permissions = 'ohos.permission.WRITE_AUDIO'
const READ_AUDIO:Permissions = 'ohos.permission.READ_AUDIO'
//跨应用关联
const APP_TRACKING_CONSENT:Permissions = 'ohos.permission.APP_TRACKING_CONSENT'
//多设备协同
const DISTRIBUTED_DATASYNC:Permissions = 'ohos.permission.DISTRIBUTED_DATASYNC'
//蓝牙
const ACCESS_BLUETOOTH:Permissions = 'ohos.permission.ACCESS_BLUETOOTH'
//剪切板
const READ_PASTEBOARD:Permissions = 'ohos.permission.READ_PASTEBOARD'
//文件夹
const READ_WRITE_DOWNLOAD_DIRECTORY:Permissions = 'ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY'
const READ_WRITE_DOCUMENTS_DIRECTORY:Permissions = 'ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY'
//星闪
const ACCESS_NEARLINK:string = 'ohos.permission.ACCESS_NEARLINK'
//文件
//读写媒体库图片或视频 推荐方案(无需申请权限):使用Picker读取媒体库的图片与视频
//读取媒体库音频文件 需申请音视频权限
//读取文件管理器中的文件 无需申请权限,通过文件Picker读写文件管理器中的文件
//PERMISSION_DENIED -1 表示未授权
//PERMISSION_GRANTED 0 表示已授权
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
export async function requestLocation(context: common.UIAbilityContext): Promise<boolean>{
let grantStatus1: boolean = await checkPermissionGrant(LOCATION) === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;// 获取精确定位权限状态
let grantStatus2: boolean = await checkPermissionGrant(APPROXIMATELY_LOCATION) === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;// 获取模糊定位权限状态
// 精确定位权限只能跟模糊定位权限一起申请,或者已经有模糊定位权限才能申请精确定位权限
if (grantStatus2 && !grantStatus1) {
// 申请精确定位权限
return reqPermissionsFromUser([LOCATION],context)
} else if (!grantStatus1 && !grantStatus2) {
// 申请模糊定位权限与精确定位权限或单独申请模糊定位权限
return reqPermissionsFromUser([LOCATION,APPROXIMATELY_LOCATION],context)
} else {
// 已经授权,可以继续访问目标操作
return true
}
}
async function checkPermissionGrant(permission: Permissions): Promise<abilityaccessctrl.grantstatus> {
// 获取应用程序的accessTokenID
let tokenId: number = 0;
let grantStatus: abilityAccessCtrl.GrantStatus = -1;
try {
let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
}
// 校验应用是否被授予权限
try {
grantStatus = await atManager.checkAccessToken(tokenId, permission);
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
}
return grantStatus;
}
async function reqPermissionsFromUser(permissions: Array<permissions>, context: common.UIAbilityContext): Promise<boolean> {
return atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let grants: number = 0;
for (let i = 0; i < grantStatus.length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
grants++
}
}
if (grants===grantStatus.length) {
return true
}
return false
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
return false
});
}
//引导用户到系统设置中打开相应的权限
export function requestPermissionOnSetting(permissions: Array<permissions>, context: common.UIAbilityContext):Promise<boolean> {
return atManager.requestPermissionOnSetting(context, permissions).then((data: Array<abilityaccessctrl.grantstatus>) => {
let grants: number = 0;
for (let i = 0; i < data.length; i++) {
if (data[i] === 0) {
// 用户授权,可以继续访问目标操作
grants++
}
}
if (grants===data.length) {
return true
}
return false
}).catch((err: BusinessError) => {
return false
});
}
</abilityaccessctrl.grantstatus></boolean></permissions></number></boolean></permissions></abilityaccessctrl.grantstatus></boolean></permissions>
以上列出了所有需要用户授权的权限,如果用到相关的用户权限,可以按照定位权限的方式动态获取。后续介绍使用 Picker 读取媒体库的图片与视频。
版权声明: 本文为 InfoQ 作者【auhgnixgnahz】的原创文章。
原文链接:【http://xie.infoq.cn/article/c9e5dcc05f1f4ee5112e5e1d5】。文章转载请联系作者。

auhgnixgnahz
还未添加个人签名 2018-07-10 加入
还未添加个人简介
评论