HarmonyOS实战开发-为应用添加运行时权限

介绍

通过AbilityAccessCtrl动态向用户申请“允许不同设备间的数据交换”的权限,使用设备管理实例获取周边不可信设备列表。

说明: 查询周边不可信设备之前,请确保本设备与周边设备未进行配对。如果已配对,则恢复出厂设置之后重新查询。

相关概念

  • 访问控制权限申请:应用的APL(Ability Privilege Level)等级分为normal、system_basic和system_core三个等级,默认情况下,应用的APL等级都为normal等级。权限类型分为system_grant和user_grant两种类型。应用可申请的权限项参见应用权限列表。
  • 权限类型说明:根据授权方式的不同,权限类型可分为system_grant(系统授权)和user_grant(用户授权)。
  • 应用ALP等级说明:元能力权限等级APL(Ability Privilege Level)指的是应用的权限申请优先级的定义,不同APL等级的应用能够申请的权限等级不同。
  • 应用权限列表:在申请目标权限前,建议开发者先阅读访问控制开发概述-权限的工作流程。对权限的工作流程有基本的了解后,再结合以下权限的具体说明,判断应用能否申请目标权限,提高开发效率。
  • 设备管理实例:用于获取可信设备和本地设备的相关信息。在调用DeviceManager的方法前,需要先通过createDeviceManager构建一个DeviceManager实例dmInstance。

约束与限制

通过DevEco Studio自动下载的SDK均为public版本,public-SDK不支持开发者使用系统API。本篇Codelab使用的DeviceManager(设备管理实例)依赖于系统API,需下载full-SDK并替换工具自动下载的public-SDK。具体操作可参考指南《如何替换full-SDK》。

相关权限

本篇Codelab需要在配置文件module.json5里添加允许不同设备间的数据交换权限:ohos.permission.DISTRIBUTED_DATASYNC。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:3.2 Release。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

2.搭建烧录环境。

  1. 完成DevEco Device Tool的安装
  2. 完成RK3568开发板的烧录

3.搭建开发环境。

  1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
  3. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets                      // 代码区
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets            // 公共常量类
│  │  └──util
│  │     ├──DeviceListUtil.ets             // 设备查询工具类
│  │     ├──Logger.ets                     // 日志管理工具类
│  │     └──PermissionUtil.ets             // 权限申请工具类
│  ├──entryability
│  │  └──EntryAbility.ts                   // 程序入口类
│  ├──pages
│  │  └──HomePage.ets                      // 主页面
│  └──view
│     ├──DeviceBean.ets                    // 设备信息类
│     ├──DeviceItem.ets                    // 设备信息对象
│     ├──DeviceListDialog.ets              // 设备列表展示弹框
│     └──NoPermissionDialog.ets            // 无权限弹框
└──entry/src/main/resource                 // 应用静态资源目录

页面设计

页面分为授权图片、授权说明、查询内网设备按钮三部分,效果如图所示:

// HomePage.ets
struct HomePage {@State authorizedImage: Resource = $r('app.media.ic_unauthorized');@State permissionDescribe: Resource = $r('app.string.no_permission');noPermissionDialog: CustomDialogController = new CustomDialogController({builder: NoPermissionDialog(),autoCancel: false,alignment: DialogAlignment.Bottom,offset: {dx: CommonConstants.DIALOG_OFFSET_X,dy: CommonConstants.DIALOG_OFFSET_Y}});deviceListDialog: CustomDialogController = new CustomDialogController({builder: DeviceListDialog(),autoCancel: false,alignment: DialogAlignment.Bottom,offset: {dx: CommonConstants.DIALOG_OFFSET_X,dy: CommonConstants.DIALOG_OFFSET_Y}})...build() {Column() {Image(this.authorizedImage)...Text(this.permissionDescribe)...Column() {Button($r('app.string.button_text'), { type: ButtonType.Capsule, stateEffect: true })...}...}...}
}

授权状态为未授权时,点击查询内网设备按钮打开未申请权限提示的弹框,效果如图所示:

// NoPermissionDialog.ets
@CustomDialog
export struct NoPermissionDialog {controller: CustomDialogController;build() {Column() {Text($r('app.string.no_permission_title'))...Text($r('app.string.clear_permission'))...Text($r('app.string.dialog_confirm'))....onClick(() => {this.controller.close();})}...}
}

授权状态为已授权时,点击查询内网设备按钮打开设备查询列表弹框,效果如图所示:

// DeviceListDialog.ets
@CustomDialog
export struct DeviceListDialog {private deviceListUtil: DeviceListUtil = new DeviceListUtil();@State deviceList: Array<DeviceBean> = [];controller: CustomDialogController;...build() {Column() {Text($r('app.string.device_list'))...Column() {if (this.deviceList.length === 0) {Text($r('app.string.no_device'))...} else {Column() {List() {ForEach(this.deviceList, (item: DeviceBean, index: number) => {ListItem() {DeviceItem({item: item, index: index});}}, (item: DeviceBean) => JSON.stringify(item))}}...}}...Text($r('app.string.dialog_confirm'))....onClick(() => {this.deviceListUtil.stopDeviceDiscovery();this.controller.close();})}...}
}

权限申请

首次进入主页面弹出授权弹框,点击禁止按钮不会授权,点击允许按钮进行授权,再次进入首页不会出现授权弹框。

// HomePage.ets
struct HomePage {...async aboutToAppear() {let result = await PermissionUtil.applyPermission();if (result === 0) {this.permissionDescribe = $r('app.string.has_permission');this.authorizedImage = $r('app.media.ic_authorized');} else {this.permissionDescribe = $r('app.string.no_permission');}}...
}// PermissionUtil.ets
async applyPermission() {let atManager = abilityAccessCtrl.createAtManager();let data = await atManager.requestPermissionsFromUser(getContext(this), [CommonConstants.PERMISSION]);let grantStatus: Array<number> = data.authResults;let length: number = grantStatus.length;if (length === 0) {return 1;}return grantStatus[0];
}

主页面点击查询内网设备按钮时,先查询是否授权,根据授权状态打开对应的弹框(未授权:打开未授权弹框;已授权:打开设备查询列表弹框)。

// HomePage.ets
struct HomePage {...build() {Column() {...Column() {Button($r('app.string.button_text'), { type: ButtonType.Capsule, stateEffect: true })....onClick(async () => {let result = await PermissionUtil.checkPermission();if(result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {this.deviceListDialog.open();} else {this.noPermissionDialog.open();}})}...}...}
}// PermissionUtil.ets
async checkPermission() {let atManager = abilityAccessCtrl.createAtManager();let grantStatus: abilityAccessCtrl.GrantStatus =  abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;let tokenId: number = 0;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 (err) {Logger.error(TAG, 'getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}');}try {grantStatus = await atManager.checkAccessToken(tokenId, CommonConstants.PERMISSION);} catch (err) {Logger.error(TAG, 'checkAccessToken failed, code is ${err.code}, message is ${err.message}');}return grantStatus;
}

设备查询

先创建dmInstance实例,再注册发现设备(deviceFoundOn)的回调方法,最后调用startDeviceDiscovery方法查询周边设备;当查询到设备之后调用deviceFoundOn方法处理设备信息。

//DeviceListDialog.ets
export struct DeviceListDialog {...aboutToAppear() {this.deviceListUtil.initDmInstance((data: DeviceInfoInterface) => {...});}...
}// DeviceListUtil.ets
// 创建dmInstance实例
initDmInstance(dealDeviceInfo: Function) {this.dealDeviceInfo = dealDeviceInfo;try {deviceManager.createDeviceManager(getContext(this).applicationInfo.name, (err, data) => {if (err) {Logger.error(TAG, 'createDeviceManager errCode:' + err.code + ',errMessage:' + err.message);return;}this.dmInstance = data;this.deviceFoundOn();this.startDeviceDiscovery();});} catch (err) {Logger.error(TAG, 'createDeviceManager err=' + JSON.stringify(err));}
}// DeviceListUtil.ets
// 注册发现设备回调方法
deviceFoundOn() {try {if (this.dmInstance !== undefined) {this.dmInstance.on('deviceFound', (data) => {if (this.dealDeviceInfo !== undefined) {this.dealDeviceInfo(data);}});}} catch (err) {Logger.error(TAG, 'deviceFoundOn err:' + JSON.stringify(err));}
}// DeviceListUtil.ets
// 发现周边设备方法
startDeviceDiscovery() {this.subscribeId = Math.floor(Math.random() * CommonConstants.RANDOM_ONE + CommonConstants.RANDOM_TWO);let subscribeInfo: SubscribeInfoInterface = {subscribeId: this.subscribeId,mode: CommonConstants.MODE,medium: 0,freq: CommonConstants.FREQ,isSameAccount: false,isWakeRemote: true,capability: 1};try {if (this.dmInstance !== undefined) {this.dmInstance.startDeviceDiscovery(subscribeInfo);}} catch (err) {Logger.error(TAG, 'startDeviceDiscovery err:' + JSON.stringify(err));}
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 访问控制授权申请。
  2. 权限类型说明。
  3. 如何获取周边设备。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等.....视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF》

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. ……

二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全
  5. ........

三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/572732.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树与二叉树的应用试题解析

01&#xff0e;在有n个叶结点的哈夫曼树中&#xff0c;非叶结点的总数是( A ). A. n-1 B. n C. 2n-1 D.2n 02.给定整数集合{3,5,6,9,12}&#xff0c;与之对应的哈夫曼树是( D…

MySQL - 高阶语句(二)

目录 6. 子查询 操作&#xff1a; EXISTS 关键字 别名 as 7. 视图 理论&#xff1a; 操作&#xff1a; 视图的优缺点 8. NULL 值 9. union 联级 9.1 union &#xff08;合并后去重&#xff09; 9.2 union all (合并后不去重) 9.3 取非交集值 10. case 条件选择查…

Vue 与 React:前端框架对比分析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

MySQL数据库(MySQL主从搭建|Django中实现MySQL读写分离|Django中使用MySQL连接池)

文章目录 一、MySQL主从搭建1.MySQL主从的目的&#xff1f;2.MySQL主从原理3.搭建步骤 二、Django中实现MySQL读写分离1.使用sqlite实现读写分离2.MySQL实现读写分离 三、Django中使用连接池1.使用池的目的2.Django中使用MySQL连接池 一、MySQL主从搭建 1.MySQL主从的目的&…

游戏开发笔记:游戏海外版本时区问题(解释时区问题,分解为js写法和lua写法来分析记录,整理出对应语言的相关函数方法。)

对于海外游戏而言,与时间相关的功能,都不能忽略时区的计算。根据 ‘ 服务端资源是有限的,客户端资源是无穷无尽的 ’的定义来说,基本上时区包括时间的计算都是由客户端来进行计算,今天内容也是围绕客户端来展开。 时区算法常见的时间描述时区需要计算的点在lua语言中的写…

鸿蒙OS开发问题:(ArkTS)【 RSA加解密,解决中文乱码等现象】

RSA加解密开始构建工具类就是举步维艰&#xff0c;官方文档虽然很全&#xff0c;但是还是有很多小瑕疵&#xff0c;在自己经过几天的时间&#xff0c;彻底解决了中文乱码的问题、分段加密的问题。 首先看官方示例代码(以RSA非对称加解密&#xff08;多次调用doFinal实现分段&a…

DevSecOps平台架构系列-互联网企业私有化DevSecOps平台典型架构

目录 一、概述 二、私有化DevSecOps平台建设思路 2.1 采用GitOps公有云建设 2.2 采用GitOps私有云建设 2.3 总结 三、GitOps及其生态组件 3.1 采用GitOps的好处 3.1.1 周边生态系统齐全 3.1.2 便于自动化的实现 3.1.3 开发人员属性GitOps 3.2 GitOps部分生态组件介绍…

苹果 WWDC 24 将举行;高通、谷歌、英特尔等联合开发 AI 软件;艺术家谈及使用 Sora 创作视频体验

▶ 苹果WWDC 24 将于当地时间 6 月 10 日召开 3 月 27 日凌晨&#xff0c;苹果官宣将于当地时间 6 月 10 日举行今年的全球开发者发布大会。 苹果全球营销高级副总裁 Greg Joswiak 在社交媒体上表示&#xff1a;「在您的日历标记上 WWDC24 吧。这场活动无疑会令人惊喜&#xf…

如何使用极狐GitLab 自定义 Pages 根域名

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了极狐GitLab Pages …

前端埋点全解及埋点SDK实现方式

一、什么是埋点 所谓“埋点”&#xff0c;是数据采集领域&#xff08;尤其是用户行为数据采集领域&#xff09;的术语&#xff0c;指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。比如用户某个icon点击次数、观看某个视频的时长等等。 埋点…

春秋云境CVE-2023-1313

简介 cockpit在2.4.1版本之前存在任意文件上传漏洞PS&#xff1a;通过在浏览器中打开/install来运行安装 正文 来到靶场&#xff0c;首先进行弱口令爆破&#xff0c;发现没用&#xff0c;那么只好老老实实的看靶场提示 先来访问/install 访问后就可以进行登录了&#xff0c…

【Bug-ModuleNotFoundError: No module named ‘models‘】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 出现这个错误&#xff1a; 出现了ModuleNotFoundError: No module named models’的问题。 文件在Model…