鸿蒙HarmonyOS开发:应用权限的基本概念及如何申请应用权限具体介绍 ...

打印 上一主题 下一主题

主题 1049|帖子 1049|积分 3147

一、访问控制

默认情况下,应用只能访问有限的系统资源。但某些情况下,应用存在扩展功能的诉求,必要访问额外的系统数据(包括用户个人数据)和功能,系统也必须以明确的方式对外提供接口来共享其数据或功能。
系统通过访问控制的机制,来避免数据或功能被不当或恶意利用。当前访问控制的机制涉及多方面,包括应用沙箱、应用权限、系统控件等方案。
二、应用权限

系统根据应用的APL等级设置进程域和数据域标签,并通过访问控制机制限定应用可访问的数据范围,从而实现在机制上消减应用数据泄露的风险。
差别APL等级的应用可以或许申请的权限等级差别,且差别的系统资源(如:通讯录等)或系统本领(如:访问摄像头、麦克风等)受差别的应用权限保护。通过严格的分层权限保护,有效抵御恶意攻击,确保系统安全可靠。
1、应用权限管控

系统提供了一种答应应用访问系统资源(如:通讯录等)和系统本领(如:访问摄像头、麦克风等)的通用权限访问方式,来保护系统数据(包括用户个人数据)或功能,避免它们被不当或恶意利用。
应用权限保护的对象可以分为数据和功能:
数据包括个人数据(如照片、通讯录、日历、位置等)、设备数据(如设备标识、相机、麦克风等)。
功能包括设备功能(如访问摄像头/麦克风、打电话、联网等)、应勤奋能(如弹出悬浮窗、创建快捷方式等)。
2、权限利用的基本原则

公道的利用场景有助于应用权限申请和利用。开发应用时权限申请必要满足如下原则:


  • 应用(包括应用引用的三方库)所需权限必须在应用的设置文件中严格按照权限开发指导逐个声明。
  • 权限申请满足最小化原则,禁止申请非必要的、已废弃的权限。应用申请过多权限,会引起用户对应用安全性的担心以及利用体验变差,从而也会影响到应用的安装率和留存率。
  • 应用申请敏感权限时,必须填写权限利用来由字段,敏感权限通常是指与用户隐私密切相关的权限,包括地理位置、相机、麦克风、日历、健身活动、身体传感器、音乐、文件、图片视频等权限。
  • 应用敏感权限须在对应业务功能执行前动态申请,满足隐私最小化要求。
  • 用户拒绝授予某个权限后,应用与此权限无关的其他业务功能应答应正常利用。
3、授权方式

根据授权方式的差别,权限范例可分为system_grant(系统授权)和user_grant(用户授权)。


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


  • user_grant(用户授权)
user_grant指的是用户授权范例,在该范例的权限允许下,应用被答应访问的数据将会涉及到用户或设备的敏感信息,应用被答应执行的操作可能对系统或者其他应用产生严重的影响。
该范例权限不仅必要在安装包中申请权限,还必要在应用动态运行时,通过发送弹窗的方式请求用户授权。在用户手动答应授权后,应用才会真正获取相应权限,从而乐成访问操作目标对象。
4、权限等级

为了防止应用过度索取和滥用权限,系统基于APL(Ability Privilege Level,元本领权限等级)等级,设置了差别的权限开放范围。
元本领权限等级APL指的是应用的权限申请优先级的定义,差别APL等级的应用可以或许申请的权限等级差别。
级别说明开放范围normal答应应用访问超出默认规则外的平凡系统资源,如设置Wi-Fi信息、调用相机拍摄等。这些系统资源的开放(包括数据和功能)对用户隐私以及其他应用带来的风险低。都能用system_basic答应应用访问操作系统底子服务(系统提供或者预置的底子功能)相关的资源,如系统设置、身份认证等。这些系统资源的开放对用户隐私以及其他应用带来的风险较高。要签名证书system_core涉及开放操作系统核心资源的访问操作。这部分系统资源是系统最核心的底层服务,如果遭受破坏,操作系统将无法正常运行。不开放 三、申请应用权限

1、选择申请权限的方式

应用在访问数据或者执行操作时,必要评估该举动是否必要应用具备相关的权限。如果确认必要目标权限,则必要在应用安装包中申请目标权限。
每一个权限的权限等级、授权方式差别,申请权限的方式也差别,开发者在申请权限前,必要先根据以下流程判定应用可否申请目标权限。



  • system_grant(系统授权)
如果目标权限是system_grant范例,开发者在进行权限申请后,系统会在安装应用时自动为其进行权限预授予,开发者不必要做其他操作即可利用权限。


  • user_grant(用户授权)
在应用必要获取user_grant权限时,请完成以下步调:
1、在设置文件中,声明应用必要请求的权限。
2、将应用中必要申请权限的目标对象与对应目标权限进行关联,让用户明确地知道,哪些操作必要用户向应用授予指定的权限。
3、运行应用时,在用户触发访问操作目标对象时应该调用接口,精准触发动态授权弹框。该接口的内部会检查当前用户是否已经授权应用所需的权限,如果当前用户尚未授予应用所需的权限,该接口会拉起动态授权弹框,向用户请求授权。
4、检查用户的授权结果,确认用户已授权才可以进行下一步操作。
2、声明权限

应用在申请权限时,必要在项目的设置文件中,逐个声明必要的权限,否则应用将无法获取授权。
应用必要在module.json5设置文件的requestPermissions标签中声明权限。
属性含义数据范例是否必填取值范围name必要利用的权限名称。字符串必填需为系统已定义的权限,取值范围请参考应用权限列表。reason申请权限的缘故原由。字符串选填该字段用于应用上架校验,当申请的权限为user_grant权限时必填,并且必要进行多语种适配。利用string类资源引用。格式为$string: ***。usedScene权限利用的场景。包括abilities和when两个子项。
-abilities:利用权限的UIAbility或者ExtensionAbility组件的名称。
- when:调用机遇。对象必填当申请的权限为user_grant权限时建议填写。 3、声明样例

// module.json5
  1. {
  2.   "module" : {
  3.     "requestPermissions":[
  4.       // 网络请求
  5.       {
  6.         "name": "ohos.permission.INTERNET"
  7.       },
  8.       // 相机
  9.       {
  10.         "name": "ohos.permission.CAMERA",
  11.         "reason": '$string:permission_reason_camera',
  12.         "usedScene": {}
  13.       },
  14.     ]
  15.   }
  16. }
复制代码
4、二次向用户申请授权

当应用通过requestPermissionsFromUser()拉起弹框请求用户授权时,用户拒绝授权。应用将无法再次通过requestPermissionsFromUser拉起弹框,必要用户在系统应用“设置”的界面中,手动授予权限。
在“设置”应用中的路径:
路径一:设置 > 隐私和安全 > 权限范例(如麦克风) > 具体应用
路径二:设置 > 应用和元服务 > 某个应用
应用也可以通过调用requestPermissionOnSetting(),直接拉起权限设置弹框,引导用户授予权限。
5、具体实现示例

以申请利用麦克风权限为例进行说明。
在UI中向用户申请授权。
调用requestPermissionsFromUser()方法后,应用程序将等待用户授权的结果。如果用户授权,则可以继续访问目标操作。如果用户拒绝授权,则必要提示用户必须授权才华访问当前页面的功能,并引导用户到系统应用“设置”中打开相应的权限。
应用也可以通过调用requestPermissionOnSetting(),直接拉起权限设置弹框,引导用户授予权限。
  1. import { abilityAccessCtrl, common, Permissions, bundleManager } from '@kit.AbilityKit'
  2. import { promptAction } from '@kit.ArkUI';
  3. const context = getContext(this) as common.UIAbilityContext;
  4. @Entry
  5. @Component
  6. struct PermissionPage {
  7.   // 打开系统设置的权限管理页
  8.   openPermissionSettingsPage() {
  9.     const BundleFlag = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
  10.     // 获取 bundle 包信息
  11.     const bundleInfo = bundleManager.getBundleInfoForSelfSync(BundleFlag)
  12.     // 通过 startAbility 打开 系统设置 页
  13.     context.startAbility({
  14.       bundleName: 'com.huawei.hmos.settings', // 固定写法CV:设置页的包名
  15.       abilityName: 'com.huawei.hmos.settings.MainAbility', // 固定写法CV:设置页的 ability 名
  16.       uri: 'application_info_entry', // 固定写法CV:打开 设置->应用和元服务
  17.       parameters: {
  18.         // 应用包名可通过 bundleManager 动态获取
  19.         pushParams: bundleInfo.name
  20.       }
  21.     })
  22.   }
  23.   // 申请麦克风授权
  24.   async requestMicrophone() {
  25.     const permissions: Array<Permissions> = ['ohos.permission.MICROPHONE'];
  26.     // 1. 创建应用权限管理器
  27.     const atManager = abilityAccessCtrl.createAtManager()
  28.     // 2. 向用户申请 user_grant 权限(温馨提示:首次申请时会弹窗,后续申请则不会再出现弹窗)
  29.     const requestResult = await atManager.requestPermissionsFromUser(
  30.       context, // 应用上下文
  31.       permissions   // 参数:权限列表(数组)zou
  32.     )
  33.     const isAuth = requestResult.authResults.every(item => item === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
  34.     // 如果点击拒绝,则弹窗引导去设置页开启
  35.     if (!isAuth) {
  36.       promptAction.showDialog({
  37.         alignment: DialogAlignment.Center,
  38.         title: '温馨提示',
  39.         message: "开启后才能录制加密视频和音频",
  40.         buttons: [
  41.           { text: '取消', color: '#89939c' },
  42.           { text: '去设置', color: '#0a59f7' },
  43.         ]
  44.       })
  45.         .then((res) => {
  46.           // 用户点击了去设置
  47.           if (res.index === 1) {
  48.             // 通过代码打开当前应用的设置页
  49.             this.openPermissionSettingsPage()
  50.           }
  51.         })
  52.     }
  53.   }
  54.   build() {
  55.     Column() {
  56.       Button('申请麦克风授权')
  57.         .onClick(() => {
  58.           this.requestMicrophone()
  59.         })
  60.     }.padding(20)
  61.     .height('100%')
  62.     .width('100%')
  63.   }
  64. }
复制代码
6、结果展示


如果用户拒绝授权,通过调用requestPermissionOnSetting(),直接拉起权限设置弹框,引导用户授予权限。

四、应用权限列表

1、system_grant(系统授权)

更多请拜见官网《对所有应用开放》
ohos.permission.USE_BLUETOOTH
答应应用检察蓝牙的设置。
ohos.permission.GET_BUNDLE_INFO
答应查询应用的基本信息。
ohos.permission.PREPARE_APP_TERMINATE
答应应用关闭前执行自定义的预关闭动作。
ohos.permission.PRINT
答应应用获取打印框架的本领。
ohos.permission.DISCOVER_BLUETOOTH
答应应用设置当地蓝牙,查找远端设备且与之配对毗连。
ohos.permission.ACCELEROMETER
答应应用读取加速度传感器的数据。
ohos.permission.ACCESS_BIOMETRIC
答应应用利用生物特性识别本领进行身份认证。
ohos.permission.ACCESS_NOTIFICATION_POLICY
在本设备上答应应用访问关照计谋。
仅当控制铃声从静音到非静音时,必要申请该权限。
ohos.permission.GET_NETWORK_INFO
答应应用获取数据网络信息。
ohos.permission.GET_WIFI_INFO
答应应用获取Wi-Fi信息。
ohos.permission.GYROSCOPE
答应应用读取陀螺仪传感器的数据。
ohos.permission.INTERNET
答应利用Internet网络。
ohos.permission.KEEP_BACKGROUND_RUNNING
答应Service Ability在配景连续运行。
ohos.permission.NFC_CARD_EMULATION
答应应用实现卡模拟功能。
ohos.permission.NFC_TAG
答应应用读写Tag卡片。
ohos.permission.PRIVACY_WINDOW
答应应用将窗口设置为隐私窗口,禁止截屏录屏
ohos.permission.PUBLISH_AGENT_REMINDER
答应该应用利用配景代理提示。
ohos.permission.SET_WIFI_INFO
答应应用设置Wi-Fi设备。
ohos.permission.VIBRATE
答应应用控制马达振动。
ohos.permission.CAMERA
答应应用利用相机。
更多请拜见官网《对所有应用开放》
2、user_grant(用户授权)

更多请拜见官网《受限开放权限》
ohos.permission.READ_AUDIO
答应读取用户公共目次的音频文件。
ohos.permission.WRITE_AUDIO
答应修改用户公共目次的音频文件。
ohos.permission.READ_IMAGEVIDEO
答应读取用户公共目次的图片或视频文件。
ohos.permission.WRITE_IMAGEVIDEO
答应修改用户公共目次的图片或视频文件。
ohos.permission.SHORT_TERM_WRITE_IMAGEVIDEO
答应应用生存图片、视频到用户公共目次。应用获取此权限后,最长可获得30分钟的短时授权,来生存图片/视频。
ohos.permission.READ_CONTACTS
答应应用读取联系人数据。
ohos.permission.WRITE_CONTACTS
答应应用添加、移除或更改联系人数据。
ohos.permission.SYSTEM_FLOAT_WINDOW
答应应用利用全局悬浮窗的本领。
ohos.permission.READ_PASTEBOARD
答应应用读取剪贴板。
更多请拜见官网《受限开放权限》
3、应用权限组列表



  • 在申请目标权限前,建议开发者先阅读应用权限管控概述-权限组和子权限,了解相关概念,再公道申请对应的权限组。
  • 当应用请求权限时,同一个权限组的权限将会在一个弹窗内一起请求用户授权,用户同意授权后,权限组内权限将被统一授权。地理位置、通讯录、通话记录、电话、信息、日历权限组除外。
  • 当前系统支持的权限组如下所示,各子权限的含义请查阅应用权限列表。
更多请拜见官网《应用权限组列表》
位置
ohos.permission.LOCATION_IN_BACKGROUND
ohos.permission.LOCATION
ohos.permission.APPROXIMATELY_LOCATION
相机
ohos.permission.CAMERA
麦克风
ohos.permission.MICROPHONE
通讯录
ohos.permission.READ_CONTACTS
ohos.permission.WRITE_CONTACTS
日历
ohos.permission.READ_CALENDAR
ohos.permission.WRITE_CALENDAR
图片和视频
ohos.permission.WRITE_IMAGEVIDEO
ohos.permission.READ_IMAGEVIDEO
ohos.permission.MEDIA_LOCATION
音乐和音频
ohos.permission.WRITE_AUDIO
ohos.permission.READ_AUDIO
文件夹
ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY
ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY
更多请拜见官网《应用权限组列表》
五、封装方法类

检查是否授权,申请授权,打开系统设置的权限管理页,逻辑都是相同的,我们通过 class 把功能进行封装整合,方便复用。
//PermissionManager.ets
  1. import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';
  2. class PermissionManager {
  3.   /**
  4.    * 检查是否授权
  5.    * @param permissions 权限列表
  6.    * @returns 返回授权结果
  7.    */
  8.   checkPermissions(permissions: Permissions[]) {
  9.     // 1. 创建应用权限管理器
  10.     const atManager = abilityAccessCtrl.createAtManager()
  11.     // 2. 获取 bundle 包信息,Sync 写法
  12.     const bundleFlag = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
  13.     const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlag)
  14.     // 3. 提取 tokenID
  15.     const tokenID = bundleInfo.appInfo.accessTokenId
  16.     // 4. 检测是否授权,Sync 写法,遍历权限组(数组)
  17.     const grantStatus = permissions.map(item => atManager.checkAccessTokenSync(tokenID, item))
  18.     // 5. 返回权限数组的检测结果
  19.     return grantStatus.every(result => result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
  20.   }
  21.   /**
  22.    * 申请授权(首次弹窗申请)
  23.    * @param permissions 权限列表
  24.    * @returns 返回授权结果,授权成功为 Promise.resolve(), 拒绝授权为 Promise.reject()
  25.    */
  26.   async requestPermissions(permissions: Permissions[]) {
  27.     // 1. 创建应用权限管理器
  28.     const atManager = abilityAccessCtrl.createAtManager()
  29.     // 2. 向用户申请 user_grant 权限(温馨提示:首次申请时会弹窗,后续申请则不会再出现弹窗)
  30.     const requestResult = await atManager.requestPermissionsFromUser(
  31.       getContext(), // 应用上下文
  32.       permissions   // 参数:权限列表(数组)
  33.     )
  34.     // 3. 通过 every 检查权限是否都成功授权
  35.     const isAuth = requestResult.authResults.every(item => item === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
  36.     // 4. 返回授权结果
  37.     // Promise.resolve()   返回 Promise 成功,await 后续代码,正常执行
  38.     // Promise.reject()    返回 Promise 错误,await 后续代码,不被执行,Promise.reject() 的结果可被 catch 捕获
  39.     return isAuth === true ? Promise.resolve(true) : Promise.reject(false)
  40.   }
  41.   /**
  42.    * 打开系统设置的权限管理页
  43.    */
  44.   openPermissionSettingsPage() {
  45.     // 1. 获取应用上下文,并通过 as 断言收窄类型为 UIAbilityContext,否则 context 默认类型无法调用 startAbility 方法
  46.     const context = getContext() as common.UIAbilityContext
  47.     // 2. 获取 bundle 包信息
  48.     const bundleFlag = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
  49.     const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlag)
  50.     // 3. 通过 startAbility 打开 系统设置 页
  51.     context.startAbility({
  52.       bundleName: 'com.huawei.hmos.settings', // 固定写法:设置页的包名
  53.       abilityName: 'com.huawei.hmos.settings.MainAbility', // 固定写法:设置页的 ability 名
  54.       uri: 'application_info_entry', // 固定写法:打开 设置->应用和元服务
  55.       parameters: {
  56.         // 通过 bundleManager 获取应用包名
  57.         pushParams: bundleInfo.name
  58.       }
  59.     })
  60.   }
  61. }
  62. // 导出 permissionManager
  63. export const permissionManager = new PermissionManager()
复制代码
利用示例
  1. // 1、检查是否已开启某些权限
  2. permissionManager.checkPermissions(['ohos.permission.READ_IMAGEVIDEO', 'ohos.permission.WRITE_IMAGEVIDEO'])
  3. // 2、申请开启某些权限
  4. try {
  5.       permissionManager.requestPermissions(['ohos.permission.MICROPHONE'])
  6.       // 允许
  7. } catch (error) {
  8.       // 禁止 -> 可以引导用户打开设置页手动开启权限
  9. }
  10. // 3、通过代码打开当前应用的设置页
  11. permissionManager.openPermissionSettingsPage()
复制代码
  注意:必要申请的权限要提前在 module.json5 中添加权限

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表