鸿蒙NEXT开发权限工具类(申请授权相关)(ArkTs)

news2025/4/23 13:37:22
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { bundleManager, common, PermissionRequestResult } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import { ToastUtil } from './ToastUtil';

/**
 * 权限工具类(申请授权相关)
 * author: CSDN-鸿蒙布道师
 * since: 2025/04/22
 */
export class PermissionUtil {
  /**
   * 获取应用上下文
   */
  private static getContext(): common.UIAbilityContext {
    return getContext() as common.UIAbilityContext;
  }

  /**
   * 创建权限管理器实例
   */
  private static createAtManager(): abilityAccessCtrl.AtManager {
    return abilityAccessCtrl.createAtManager();
  }

  /**
   * 校验当前是否已经授权
   * @param permission 待判断的权限
   * @returns 已授权 true,未授权 false
   */
  static async checkPermissions(permission: Permissions): Promise<boolean> {
    const grantStatus = await PermissionUtil.checkAccessToken(permission);
    return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
  }

  /**
   * 校验并申请权限
   * @param permissions 需要授权的权限
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async checkAndRequestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const isGranted = await PermissionUtil.checkPermissions(permissions as Permissions);
    if (isGranted) {
      return true;
    }
    return PermissionUtil.requestPermissionsEasy(permissions);
  }

  /**
   * 申请权限(支持单个或多个权限组合)
   * @param permissions 需要授权的权限
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const atManager = PermissionUtil.createAtManager();
    const context = PermissionUtil.getContext();
    const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];

    try {
      const result = await atManager.requestPermissionsFromUser(context, permissionArray);
      return PermissionUtil.isPermissionGranted(result);
    } catch (error) {
      PermissionUtil.handleError(error, '申请权限失败');
      return false;
    }
  }

  /**
   * 申请权限并提供二次授权机会(推荐使用此方法)
   * @param permissions 需要授权的权限
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissionsEasy(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const granted = await PermissionUtil.requestPermissions(permissions);
    if (granted) {
      return true;
    }
    return PermissionUtil.requestPermissionOnSettingEasy(
      Array.isArray(permissions) ? [...permissions] : [permissions]
    );
  }

  /**
   * 二次向用户申请权限(适用于单个权限或读写权限组)
   * @param permissions 需要授权的权限集合
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissionOnSetting(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const atManager = PermissionUtil.createAtManager();
    const context = PermissionUtil.getContext();
    const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];

    try {
      const result = await atManager.requestPermissionOnSetting(context, permissionArray);
      return PermissionUtil.isPermissionGranted(result);
    } catch (error) {
      PermissionUtil.handleError(error, '二次申请权限失败');
      return false;
    }
  }

  /**
   * 二次向用户申请权限(适用于多个权限)
   * @param permissions 需要授权的权限集合
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissionOnSettingEasy(permissions: Array<Permissions>): Promise<boolean> {
    for (const permission of permissions) {
      const isGranted = await PermissionUtil.checkPermissions(permission);
      if (!isGranted) {
        const granted = await PermissionUtil.requestPermissionOnSetting(permission);
        if (!granted) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * 检查权限是否已授予
   * @param data 授权结果
   * @returns true 表示所有权限均已授予,false 表示存在未授予权限
   */
  private static isPermissionGranted(data: PermissionRequestResult | Array<number>): boolean {
    const authResults = Array.isArray(data) ? data : data.authResults;
    return authResults.every((status) => status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED);
  }

  /**
   * 校验访问令牌是否已授权
   * @param permission 待检查权限
   * @returns 授权状态
   */
  private static async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
    const atManager = PermissionUtil.createAtManager();
    let tokenId = 0;

    try {
      const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
      tokenId = bundleInfo.appInfo.accessTokenId;
    } catch (error) {
      PermissionUtil.handleError(error, '获取应用信息失败');
      return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
    }

    try {
      return await atManager.checkAccessToken(tokenId, permission);
    } catch (error) {
      PermissionUtil.handleError(error, '校验授权信息失败');
      return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
    }
  }

  /**
   * 错误处理方法
   * @param error 错误对象(明确指定为 BusinessError 类型)
   * @param message 提示信息
   */
  private static handleError(error: BusinessError, message: string): void {
    console.error(`${message}: ${error.message}`);
    ToastUtil.showToast(`${message}: ${error.message}`);
  }
}

代码如下:
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { bundleManager, common, PermissionRequestResult } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import { ToastUtil } from './ToastUtil';

/**
 * 权限工具类(申请授权相关)
 * author: CSDN-鸿蒙布道师
 * since: 2025/04/22
 */
export class PermissionUtil {
  /**
   * 获取应用上下文
   */
  private static getContext(): common.UIAbilityContext {
    return getContext() as common.UIAbilityContext;
  }

  /**
   * 创建权限管理器实例
   */
  private static createAtManager(): abilityAccessCtrl.AtManager {
    return abilityAccessCtrl.createAtManager();
  }

  /**
   * 校验当前是否已经授权
   * @param permission 待判断的权限
   * @returns 已授权 true,未授权 false
   */
  static async checkPermissions(permission: Permissions): Promise<boolean> {
    const grantStatus = await PermissionUtil.checkAccessToken(permission);
    return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
  }

  /**
   * 校验并申请权限
   * @param permissions 需要授权的权限
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async checkAndRequestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const isGranted = await PermissionUtil.checkPermissions(permissions as Permissions);
    if (isGranted) {
      return true;
    }
    return PermissionUtil.requestPermissionsEasy(permissions);
  }

  /**
   * 申请权限(支持单个或多个权限组合)
   * @param permissions 需要授权的权限
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const atManager = PermissionUtil.createAtManager();
    const context = PermissionUtil.getContext();
    const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];

    try {
      const result = await atManager.requestPermissionsFromUser(context, permissionArray);
      return PermissionUtil.isPermissionGranted(result);
    } catch (error) {
      PermissionUtil.handleError(error, '申请权限失败');
      return false;
    }
  }

  /**
   * 申请权限并提供二次授权机会(推荐使用此方法)
   * @param permissions 需要授权的权限
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissionsEasy(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const granted = await PermissionUtil.requestPermissions(permissions);
    if (granted) {
      return true;
    }
    return PermissionUtil.requestPermissionOnSettingEasy(
      Array.isArray(permissions) ? [...permissions] : [permissions]
    );
  }

  /**
   * 二次向用户申请权限(适用于单个权限或读写权限组)
   * @param permissions 需要授权的权限集合
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissionOnSetting(permissions: Permissions | Array<Permissions>): Promise<boolean> {
    const atManager = PermissionUtil.createAtManager();
    const context = PermissionUtil.getContext();
    const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];

    try {
      const result = await atManager.requestPermissionOnSetting(context, permissionArray);
      return PermissionUtil.isPermissionGranted(result);
    } catch (error) {
      PermissionUtil.handleError(error, '二次申请权限失败');
      return false;
    }
  }

  /**
   * 二次向用户申请权限(适用于多个权限)
   * @param permissions 需要授权的权限集合
   * @returns true 表示授权成功,false 表示用户拒绝授权
   */
  static async requestPermissionOnSettingEasy(permissions: Array<Permissions>): Promise<boolean> {
    for (const permission of permissions) {
      const isGranted = await PermissionUtil.checkPermissions(permission);
      if (!isGranted) {
        const granted = await PermissionUtil.requestPermissionOnSetting(permission);
        if (!granted) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * 检查权限是否已授予
   * @param data 授权结果
   * @returns true 表示所有权限均已授予,false 表示存在未授予权限
   */
  private static isPermissionGranted(data: PermissionRequestResult | Array<number>): boolean {
    const authResults = Array.isArray(data) ? data : data.authResults;
    return authResults.every((status) => status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED);
  }

  /**
   * 校验访问令牌是否已授权
   * @param permission 待检查权限
   * @returns 授权状态
   */
  private static async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
    const atManager = PermissionUtil.createAtManager();
    let tokenId = 0;

    try {
      const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
      tokenId = bundleInfo.appInfo.accessTokenId;
    } catch (error) {
      PermissionUtil.handleError(error, '获取应用信息失败');
      return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
    }

    try {
      return await atManager.checkAccessToken(tokenId, permission);
    } catch (error) {
      PermissionUtil.handleError(error, '校验授权信息失败');
      return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
    }
  }

  /**
   * 错误处理方法
   * @param error 错误对象(明确指定为 BusinessError 类型)
   * @param message 提示信息
   */
  private static handleError(error: BusinessError, message: string): void {
    console.error(`${message}: ${error.message}`);
    ToastUtil.showToast(`${message}: ${error.message}`);
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动驾驶与机器人算法学习

自动驾驶与机器人算法学习 直播与学习途径 欢迎你的点赞关注~

【网络编程】TCP数据流套接字编程

目录 一. TCP API 二. TCP回显服务器-客户端 1. 服务器 2. 客户端 3. 服务端-客户端工作流程 4. 服务器优化 TCP数据流套接字编程是一种基于有连接协议的网络通信方式 一. TCP API 在TCP编程中&#xff0c;主要使用两个核心类ServerSocket 和 Socket ServerSocket Ser…

从零开始配置 Zabbix 数据库监控:MySQL 实战指南

Zabbix作为一款开源的分布式监控工具&#xff0c;在监控MySQL数据库方面具有显著优势&#xff0c;能够为数据库的稳定运行、性能优化和故障排查提供全面支持。以下是使用Zabbix监控MySQL数据库的配置。 一、安装 Zabbix Agent 和 MySQL 1. 安装 Zabbix Agent services:zabbix…

Java学习手册:RESTful API 设计原则

一、RESTful API 概述 REST&#xff08;Representational State Transfer&#xff09;即表述性状态转移&#xff0c;是一种软件架构风格&#xff0c;用于设计网络应用程序。RESTful API 是符合 REST 原则的 Web API&#xff0c;通过使用 HTTP 协议和标准方法&#xff08;GET、…

读一篇AI论文并理解——通过幻觉诱导优化缓解大型视觉语言模型中的幻觉

目录 论文介绍 标题 作者 Publish Date Time PDF文章下载地址 文章理解分析 &#x1f4c4; 中文摘要&#xff1a;《通过幻觉诱导优化缓解大型视觉语言模型中的幻觉》 &#x1f9e0; 论文核心动机 &#x1f680; 创新方法&#xff1a;HIO&#xff08;Hallucination-In…

IOT项目——物联网 GPS

GeoLinker - 物联网 GPS 可视化工具 项目来源制作引导 项目来源 [视频链接] https://youtu.be/vi_cIuxDpcA?sigMaOKv681bAirQF8 想要在任何地方追踪任何东西吗&#xff1f;在本视频中&#xff0c;我们将向您展示如何使用 ESP32 和 Neo-6M GPS 模块构建 GPS 跟踪器——这是一…

Java学习手册:HTTP 协议基础知识

一、HTTP 协议概述 HTTP&#xff08;HyperText Transfer Protocol&#xff09;即超文本传输协议&#xff0c;是用于从万维网&#xff08;WWW&#xff1a;World Wide Web &#xff09;服务器传输超文本到本地浏览器的传输协议。它是一个应用层协议&#xff0c;基于请求-响应模型…

【含文档+PPT+源码】基于微信小程序的健康饮食食谱推荐平台的设计与实现

课程目标&#xff1a; 教你从零开始部署运行项目&#xff0c;学习环境搭建、项目导入及部署&#xff0c;含项目源码、文档、数据库、软件等资料 课程简介&#xff1a; 本课程演示的是一款基于微信小程序的健康饮食食谱推荐平台的设计与实现&#xff0c;主要针对计算机相关专…

Redis 慢查询分析与优化

Redis 慢查询分析与优化 参考书籍 &#xff1a; https://weread.qq.com/web/reader/d5432be0813ab98b6g0133f5kd8232f00235d82c8d161fb2 以下从配置参数、耗时细分、分析工具、优化策略四个维度深入解析 Redis 慢查询问题&#xff0c;结合实战调优建议&#xff0c;帮助开发者…

使用达梦官方管理工具SQLark快速生成数据库ER图并导出

在数据库设计与开发中&#xff0c;实体-关系图&#xff08;ER 图&#xff09;作为数据建模的核心工具&#xff0c;能够直观呈现表结构、字段属性及表间关系&#xff0c;是团队沟通和文档维护的重要工具。然而&#xff0c;许多开发者在实际工作中常面临一个痛点&#xff1a;手动…

模型 替罪羊效应

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。转嫁罪责于无辜&#xff0c;维系群体控制与稳定 1 替罪羊效应的应用 1.1 多品牌危机中的行业“背锅侠” 行业背景&#xff1a;食品行业爆发大规模安全危机&#xff0c;多家企业卷入某类食品重金属超标…

TapData × 梦加速计划 | 与 AI 共舞,TapData 携 AI Ready 实时数据平台亮相加速营,企业数据基础设施现代化

在实时跃动的数据节拍中&#xff0c;TapData 与 AI 共舞&#xff0c;踏出智能未来的新一步。 4月10日&#xff0c;由前海产业发展集团、深圳市前海梦工场、斑马星球科创加速平台等联合发起的「梦加速计划下一位独角兽营」正式启航。 本次加速营以“打造下一位独角兽企业”为目…

15.电感特性在EMC设计中的运用

电感特性在EMC设计中的运用 1. 共模电感与差模电感的差异2. 电感的高频等效特性![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b4dc000672af4dd69a528450eb42cf10.png)3. 电感在EMC设计中的使用注意事项3.1 LC滤波计算3.2 并联型多级浪涌防护的电感退耦 1. 共模电感…

uniapp Vue2升级到Vue3,并发布到微信小程序的快捷方法

目录 前言&#xff1a;升级项目的两种方式步骤一、新建项目 【选择-默认模版】二、修改-pages.json三、补充-缺少的文件四、修改-Main.js按照 [官方文档-vue2升级vue3迁移指南](https://uniapp.dcloud.net.cn/tutorial/migration-to-vue3.html) 修改 五、升级-uni-ui扩展组件的…

数据重构如何兼顾效率与性能稳定?zStorage 全闪存分布式存储的技术实践与实测数据

点击蓝字 关注我们 zStorage 作为数据库场景下的全闪存分布式存储&#xff0c;除了性能要好&#xff0c;更重要的是要在各种情况下都能保持“稳定”的好。一个高并发的交易型业务数据库&#xff0c;如果出现轻微的IO抖动&#xff0c;就可能造成数据库并发事务提交的排队&#x…

A2A + MCP:构建实用人工智能系统的超强组合

构建真正有效的连接型人工智能系统的挑战 如果你正在构建人工智能应用&#xff0c;这种情况可能听起来很熟悉&#xff1a; 你需要特定的人工智能能力来解决业务问题。你找到了完成每个单独任务的出色工具。但把所有东西连接在一起却占据了大部分开发时间&#xff0c;还创建了…

力扣每日打卡17 49. 字母异位词分组 (中等)

力扣 49. 字母异位词分组 中等 前言一、题目内容二、解题方法1. 哈希函数2.官方题解2.1 前言2.2 方法一&#xff1a;排序2.2 方法二&#xff1a;计数 前言 这是刷算法题的第十七天&#xff0c;用到的语言是JS 题目&#xff1a;力扣 49. 字母异位词分组 (中等) 一、题目内容 给…

Word处理控件Spire.Doc系列教程:C# 为 Word 文档设置背景颜色或背景图片

在 Word 文档中&#xff0c;白色是默认的背景设置。一般情况下&#xff0c;简洁的白色背景足以满足绝大多数场景的使用需求。但是&#xff0c;如果您需要创建简历、宣传册或其他创意文档&#xff0c;设置独特的背景颜色或图片能够极大地增强文档的视觉冲击力。本文将演示如何使…

掌握 Altium Designer:轻松定制“交换器件”工具栏

在PCB设计过程中&#xff0c;快速交换器件&#xff08;如电阻、电容、IC等&#xff09;是提高效率的关键。Altium Designer提供了灵活的工具栏定制功能&#xff0c;让用户可以创建专属的"交换器件"工具栏&#xff0c;将常用操作集中管理&#xff0c;减少菜单切换时间…

【C++ Qt】信号和槽(内配思维导图 图文并茂 通俗易懂)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是Qt中的第三章&#xff0c;也是我们理解Qt中必备的点 信号槽&#xff0c;它本质由信号和槽两个来实现&#xff0c;其中将细致的讲述如何自定义信号…