鸿蒙原生应用元服务-访问控制(权限)开发Stage模型向用户申请授权

embedded/2024/9/24 6:34:48/

一、向用户申请授权
当应用需要访问用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等,应该向用户请求授权。这需要使用 user_grant 类型权限。在此之前,应用需要进行权限校验,以判断当前调用者是否具备所需的权限。如果权限校验结果表明当前应用尚未被授权该权限,则应使用动态弹框授权方式,为用户提供手动授权的入口。示意效果如下图所示。

图1 向用户申请授权

鸿蒙原生应用元服务-访问控制(权限)开发Stage模型向用户申请授权-鸿蒙开发者社区

说明,每次访问受目标权限保护的接口之前,都需要使用 requestPermissionsFromUser() 接口请求相应的权限。用户可能在动态授予权限后通过系统设置来取消应用的权限,因此不能将之前授予的授权状态持久化。

二、Stage模型
以允许应用读取日历信息为例进行说明。

1.申请ohos.permission.READ_CALENDAR权限。

2.校验当前是否已经授权。

在进行权限申请之前,需要先检查当前应用程序是否已经被授予了权限。可以通过调用checkAccessToken()方法来校验当前是否已经授权。如果已经授权,则可以直接访问目标操作,否则需要进行下一步操作,即向用户申请授权。

import bundleManager from '@ohos.bundle.bundleManager';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {let atManager = abilityAccessCtrl.createAtManager();let grantStatus: abilityAccessCtrl.GrantStatus;// 获取应用程序的accessTokenIDlet tokenId: number;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) {console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);}// 校验应用是否被授予权限try {grantStatus = await atManager.checkAccessToken(tokenId, permission);} catch (err) {console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`);}return grantStatus;
}async function checkPermissions(): Promise<void> {const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]);if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {// 已经授权,可以继续访问目标操作} else {// 申请日历权限}
}

3.动态向用户申请授权。
动态向用户申请权限是指在应用程序运行时向用户请求授权的过程。可以通过调用requestPermissionsFromUser()方法来实现。该方法接收一个权限列表参数,例如位置、日历、相机、麦克风等。用户可以选择授予权限或者拒绝授权。
说明,系统不鼓励频繁弹窗打扰用户,如果用户拒绝授权,将无法再次拉起弹窗。需要应用引导用户在系统应用“设置”的界面中手动授予权限。
可以在UIAbility的onWindowStageCreate()回调中调用requestPermissionsFromUser()方法来动态申请权限,也可以根据业务需要在UI中向用户申请授权。
在UIAbility中向用户申请授权。

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];export default class EntryAbility extends UIAbility {// ...onWindowStageCreate(windowStage: window.WindowStage) {// Main window is created, set main page for this abilitylet context = this.context;let atManager = abilityAccessCtrl.createAtManager();// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗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) {// 用户授权,可以继续访问目标操作} else {// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限return;}}// 授权成功}).catch((err) => {console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);})// ...}
}

在UI中向用户申请授权。

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];@Entry
@Component
struct Index {reqPermissionsFromUser(permissions: Array<Permissions>): void {let context = getContext(this) as common.UIAbilityContext;let atManager = abilityAccessCtrl.createAtManager();// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗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) {// 用户授权,可以继续访问目标操作} else {// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限return;}}// 授权成功}).catch((err) => {console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);})}// 页面展示build() {// ...}
}

4.处理授权结果。
调用requestPermissionsFromUser()方法后,应用程序将等待用户授权的结果。如果用户授权,则可以继续访问目标操作。如果用户拒绝授权,则需要提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限。

function openPermissionsInSystemSettings(): void {let context = getContext(this) as common.UIAbilityContext;let wantInfo = {action: 'action.settings.app.info',parameters: {settingsParamBundleName: 'com.example.myapplication' // 打开指定应用的详情页面}}context.startAbility(wantInfo).then(() => {// ...}).catch((err) => {// ...})
}

本文根据HarmonyOS官方文档API9整理


http://www.ppmy.cn/embedded/7141.html

相关文章

十大开源机器人 智能体

1- Poppy 网址 https://www.poppy-project.org/en/ 2- Nao 网址:https://www.aldebaran.com/en/nao 3- iCub 网址: https://icub.iit.it/

开发语言漫谈-rust

前面介绍C语言家族时忘掉了rust&#xff0c;紧急补一篇。我们称C语言家族是指他们的语法相似&#xff0c;类似这样的&#xff1a; if(){}else{}就是C家族的。C、C的传统领域就是系统底层、硬件接口方向。C/C没有垃圾内存回收机制&#xff0c;完全靠程序员的自觉天赋&#xff0…

DDoS攻击趋势分析及防御建议:网络安全新挑战与应对策略

在数字化日益普及的今天&#xff0c;网络安全问题日益凸显。其中&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击以其巨大的破坏力和难以防范的特性&#xff0c;发起简单、效果显著、难以追踪等特点&#xff0c;因此被黑客广泛使用&#xff0c;已经成为网络安全领…

2024团体程序设计天梯赛L1-101 别再来这么多猫娘了!

题目链接L1-101 别再来这么多猫娘了&#xff01; #include<iostream> #include<stdio.h> #include<string.h> #include<string> #include<algorithm> using namespace std; string s[105], text; int n, k, ans, a[5005];int main() { // ios::s…

HarmonyOS开发实例:【任务延时调度】

介绍 本示例使用[ohos.WorkSchedulerExtensionAbility] 、[ohos.net.http]、[ohos.notification] 、[ohos.bundle]、[ohos.fileio] 等接口&#xff0c;实现了设置后台任务、下载更新包 、保存更新包、发送通知 、安装更新包实现升级的功能。 效果预览 使用说明 安装本应用之…

【UnityShader预备知识】内置变量和函数

一、转换 名称值UNITY_MATRIX_MVP当前模型 * 视图 * 投影矩阵。UNITY_MATRIX_MV当前模型 * 视图矩阵。UNITY_MATRIX_V当前视图矩阵。UNITY_MATRIX_P当前投影矩阵。UNITY_MATRIX_VP当前视图 * 投影矩阵。UNITY_MATRIX_T_MV模型转置 * 视图矩阵。UNITY_MATRIX_IT_MV模型逆转置 *…

1688API接口开发系列:商品详情数据接口丨关键词搜索商品列表丨按图搜索商品丨工厂详情等

1688 API接口开发系列涉及多个接口&#xff0c;包括商品详情数据接口、关键词搜索商品列表接口、按图搜索商品接口以及工厂详情接口等。以下是对这些接口的一般使用流程的概述&#xff1a; 1.请求方式&#xff1a;HTTP POST GET &#xff08;复制薇&#xff1a;Anzexi58 获取 …

Unity 计时任务管理器TimeHandle

前言 项目体量过大时&#xff0c;在很多脚本用到了携程计时或者写在update里面&#xff0c;不方便管理和代码阅读&#xff0c;很容易混淆&#xff0c;所以需要一个计时任务管理器来统一控制计时器模块&#xff0c;便于修改、管理。计时器有很多种写法&#xff0c;我这里写的是适…