当前位置: 首页 > ds >正文

HarmonyOS权限管理应用

权限管理

1. 权限管理概述

系统有一些比较敏感的数据和功能(通讯录、麦克风等),不能让应用软件随便访问,所以华为提供了一套授权管理机制来保护系统数据和功能,避免它们被不当或者恶意使用。
应用权限保护的对象可以分为数据和功能:
● 数据包括个人数据(如照片、通讯录、日历、位置等)、设备数据(如设备标识、相机、麦克风等)。
● 功能包括设备功能(如访问摄像头/麦克风、打电话、联网等)、应用功能(如弹出悬浮窗、创建快捷方式等)。

2. 授权方式

根据授权方式的不同,权限类型可分为system_grant(系统授权)和user_grant(用户授权)。

2.1 system_grant(系统授权)

🌶 system_grant指的是系统授权类型,在该类型的权限许可下,应用被允许访问的数据不会涉及到用户或设备的敏感信息,应用被允许执行的操作对系统或者其他应用产生的影响可控。
应用中申请了system_grant权限,系统会在用户安装应用时自动把相应权限授予给用户。

下面是一些常用的系统授权,比如:网络,蓝牙等

ohos.permission.INTERNET
允许使用Internet网络。
权限级别:normal
授权方式:system_grant
起始版本:9

2.2 user_grant(用户授权)

user_grant指的是用户授权类型,在该类型的权限许可下,应用被允许访问的数据将会涉及到用户或设备的敏感信息,应用被允许执行的操作可能对系统或者其他应用产生严重的影响。
user_grant类型权限不仅需要在安装包中申请权限,还需要在应用动态运行时,通过发送弹窗的方式请求用户授权。

在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。

ohos.permission.MICROPHONE
允许应用使用麦克风。
权限级别:normal
授权方式:user_grant
起始版本:8

3. 申请网络权限

网络权限是属于系统权限,是最基本的功能,申请权限也比较简单。应用需要在module.json5配置文件的requestPermissions标签中声明权限

3.1 配置网络权限

{"module": {"requestPermissions": [{"name": "ohos.permission.INTERNET"}]}
}

3.2 使用网络

Image("https://res2.vmallres.com/pimages/uomcdn/CN/pms/202403/gbom/6942103109577/428_428_326614F60FB96289584CA7B9E4AE7CB9mp.png").width(200).height(200)

4. 申请麦克风权限

4.1 配置ohos.permission.MICROPHONE权限

应用需要在module.json5的配置文件中逐个声明需要的权限,否则应用将无法获取授权

{"module" : {// ..."requestPermissions": [{"name": "ohos.permission.MICROPHONE",		//权限名称(这里是麦克风权限)"reason": "$string:MICROPHONE_REASON",	//原因"usedScene": {													//该权限由谁发起"abilities": ["EntryAbility"],				//由EntryAbility发起"when": "always"											//发起时机(inuse使用时允许、always总是允许)}}],}
}

4.2 动态申请麦克风授权

动态申请授权指的是拉起系统授权弹窗,让用户选择“允许”或“禁止”,只有用户选择“允许”的情况下,才可以执行目标操作。我们以获取麦克风权限为例,让用户选择是否允许授权

let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
atManager.requestPermissionsFromUser(getContext(this),['ohos.permission.MICROPHONE']).then((data) => {let grantStatus: Array<number> = data.authResultslet length: number = grantStatus.length;for (let i = 0; i < length; i++) {if (grantStatus[i] === 0) {// 用户授权成功,可以继续访问目标操作console.info("授权成功,可以继续访问目标操作")} else {// 用户授权失败,不可以执行目标操作console.info("授权失败,不可以执行目标操作")}}
}).catch((err: BusinessError) => {console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
});

4.3 校验当前应用是否已经授权

因为无法保证用户是否“允许”授权,所以每次在执行目标操作前,都需要进行检查是否有权限。可以通过调用checkAccessToken()方法来校验当前是否已经授权,如果已经授权,则可以直接访问目标操作;如果没有授权则提醒用户到系统设置手动打开应用权限。

//1.1 获取控制管理器
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()//1.2 获取应用程序的tokenId,它是应用程序的身份标识
let tokenId: number = 0;
try {let bundleInfo: bundleManager.BundleInfo =bundleManager.getBundleInfoForSelfSync(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}`);
}//1.3 校验应用是否被授予权限
let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED
try {grantStatus = atManager.checkAccessTokenSync(tokenId, 'ohos.permission.MICROPHONE');
} catch (error) {const err: BusinessError = error as BusinessError;console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
}//1.4 根据授权状态,决定是否执行目标操作
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {//TODO 授权成功,执行已经授权的业务代码console.info("已经有授权,可以执行目标操作")
} else if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {//TODO 没有授权,引导用户去设置界面打开麦克风权限console.info("没有授权,不能执行目标操作")
}

下面是打开系统设置的代码

gotoSystemSetting() {const buildInfo =bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)const context = getContext() as common.UIAbilityContextcontext.startAbility({bundleName: 'com.huawei.hmos.settings',abilityName: 'com.huawei.hmos.settings.MainAbility',uri: "application_info_entry",parameters: {pushParams: buildInfo.name}})
}

5. 封装权限工具类

5.1 权限工具类

import bundleManager from '@ohos.bundle.bundleManager';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { BusinessError, Callback } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';export class PermissionsUtils {/*** 校验应用是否具备制定的权限许可,返回权限许可状态* @param permission  指定权限* @returns 返回许可状态*/public static checkPermissionGrant(permission: Permissions, callback: Callbacks) {//1.1 获取控制管理器let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()//1.2 获取应用程序的tokenId,它是应用程序的身份标识let tokenId: number = 0;try {let bundleInfo: bundleManager.BundleInfo =bundleManager.getBundleInfoForSelfSync(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}`);}//1.3 校验应用是否被授予权限let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIEDtry {grantStatus = atManager.checkAccessTokenSync(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}`);}//1.4 根据授权状态if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {//授权成功,执行已经授权的业务代码callback.onSuccess && callback.onSuccess()} else if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {if (callback.onFailed) {callback.onFailed()} else {//没有授权,引导用户去设置界面打开麦克风权限PermissionsUtils.gotoSystemSetting();}}return grantStatus}//2.动态请求用户授权public static requestPermissionsFromUser(permissions: Array<Permissions>,callback: Callbacks) {let context = getContext() as common.UIAbilityContextlet atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();atManager.requestPermissionsFromUser(context, 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) {// 用户授权,可以继续访问目标操作callback.onSuccess && callback.onSuccess()} else {// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限callback.onFailed && callback.onFailed();}}// 授权成功}).catch((err: BusinessError) => {console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);});}public static gotoSystemSetting() {const buildInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);const context = getContext() as common.UIAbilityContext;context.startAbility({bundleName: 'com.huawei.hmos.settings',abilityName: 'com.huawei.hmos.settings.MainAbility',uri: "application_info_entry",parameters: {pushParams: buildInfo.name}});}
}interface Callbacks {onSuccess?: () => voidonFailed?: () => void
}

5.2 工具类申请权限

PermissionsUtils.requestPermissionsFromUser(['ohos.permission.MICROPHONE'], {onSuccess: () => {console.info("申请麦克风权限成功")},onFailed:()=>{console.info("申请麦克风权限失败")}
})

5.3 工具类检查权限

PermissionsUtils.checkPermissionGrant("ohos.permission.MICROPHONE",{onSuccess:()=>{console.info("已经有权限,可以访问目标操作")},onFailed:()=>{console.info("没有权限,去系统设置打开权限")PermissionsUtils.gotoSystemSetting()}
})

6.申请地理位置权限

在这里插入图片描述

6.1 配置地理位置权限

ohos.permission.APPROXIMATELY_LOCATION
允许应用获取设备模糊位置信息。
权限级别:normal
授权方式:user_grant
起始版本:9

先在modeule.json5配置文件中加入权限配置

{"module" : {"requestPermissions":[{"name": "ohos.permission.APPROXIMATELY_LOCATION","reason": "$string:permission_location","usedScene": {"abilities": ["EntryAbility"]}}]}
}

6.2 获取地理位置经纬度

import { geoLocationManager } from '@kit.LocationKit';
import { PermissionsUtils } from '../utils/PermissionsUtils';@Entry
@Component
struct Index {@State result: geoLocationManager.Location = {} as geoLocationManager.Location@State lcoationPermission: boolean = false//进入页面,时申请位置权限aboutToAppear(): void {PermissionsUtils.requestPermissionsFromUser(['ohos.permission.APPROXIMATELY_LOCATION'],{onSuccess: () => {this.lcoationPermission = true}})}build() {Column() {//点击按钮时,获取经纬度Button('获取经纬度').onClick(async () => {if (this.lcoationPermission) {this.result = await geoLocationManager.getCurrentLocation()}})Text('经度:' + this.result.latitude)Text('纬度:' + this.result.longitude)}.height('100%')}
}
http://www.xdnf.cn/news/19224.html

相关文章:

  • 【序列晋升】20 Spring Cloud Function 函数即服务(FaaS)
  • FPGA实现1553B BC控制器IP方案
  • LeetCode259~282题解
  • 吴恩达机器学习作业五:神经网络正向传播
  • 【前端教程】从性别统计类推年龄功能——表单交互与数据处理进阶
  • 【前端教程】从零开始学JavaScript交互:7个经典事件处理案例解析
  • C++Primer笔记——第六章:函数(下)
  • KNN算法(K近邻算法)
  • 互联网大厂AI大模型面试解析:从基础技术到场景应用
  • STL容器的连续性及其访问:vector和deque
  • 零基础上手:Cursor + MCP 爬取 YouTube 视频数据
  • 微信小程序中蓝牙打印机中文编码处理:使用iconv-lite库
  • Pytest 插件:pytest_runtest_protocol
  • 在Excel和WPS表格中隔一行插入多个空白行
  • nvm使用和node使用
  • 神经语言学视角:脑科学与NLP深层分析技术的交叉融合
  • YARN架构解析:深入理解Hadoop资源管理核心
  • Pycharm 登录 Github 失败
  • 从电网监控到油气分析:QtitanDataGrid 在能源领域的应用探索
  • Ubuntu下配置并远程连接MySQL
  • GVIM-您的化学多智能体助手
  • 如何用 Kotlin 在 Android 手机开发一个应用程序获取国家或地区信息
  • 瞬态数据表定义Fluent变量
  • [Godot] C#获取MenuButton节点索引
  • 将数据赋值到Word并下载
  • 2025.8.29总结
  • 从Cloudflare到EdgeOne:我的个人站点加速之旅与性能对比实测
  • Ubuntu 搭建 Solana 区块链开发环境 + Anchor 智能合约完整教程
  • Linux-搭建DNS服务器
  • C++异常处理指南:构建健壮程序的错误处理机制