OpenHarmony 权限统一封装 PermissionUtil(动态权限申请全套方案 API23+)

发布时间:2026/7/17 0:50:58

OpenHarmony 权限统一封装 PermissionUtil(动态权限申请全套方案 API23+)
摘要鸿蒙将权限分为安装时静态权限与运行时动态敏感权限相机、相册、文件、通知、位置等都必须动态申请原生权限 API 重复代码多、缺少永久拒绝跳转设置页逻辑、无统一弹窗提示、未做权限状态判断封装。本文基于ohos.accessToken封装全局权限工具类整合相机、相册、存储、通知、定位全套常用权限申请逻辑包含权限已授予 / 临时拒绝 / 永久拒绝三种状态分支处理搭配弹窗引导用户开启权限适配页面拍照、上传图片、本地文件读写、消息通知等业务场景。API23 重构 accessToken 权限校验、权限请求回调、应用设置页跳转接口修复多权限并发申请错乱、永久拒绝无引导、权限状态判断失效、页面销毁权限弹窗残留等问题。关键词OpenHarmonyArkTSAPI23accessToken动态权限Permission权限申请跳转应用设置页一、引言1.1 动态权限开发痛点每次调用相机 / 相册都要重复写权限判断、申请逻辑大量冗余代码用户选择永久拒绝权限后再次申请不会弹出授权框缺少跳转系统设置引导多权限同时申请存储 相机并发回调错乱无统一弹窗提示告知用户该功能需要对应权限页面销毁后权限申请回调执行页面变量报错无法统一封装权限授予 / 拒绝回调业务页面重复写分支逻辑。1.2 动态权限分类高频业务表格权限名称用途ohos.permission.CAMERA相机拍照ohos.permission.READ_MEDIA_IMAGES读取相册图片ohos.permission.WRITE_MEDIA保存图片到相册ohos.permission.NOTIFICATION_AGENT系统通知推送ohos.permission.READ_FOLDER沙盒外部文件读写ohos.permission.LOCATION定位获取坐标API23 accessToken 核心升级标准化checkAccessTokenSync同步校验权限状态简化异步判断权限请求结果细分三种状态已授权、临时拒绝、永久拒绝新增统一跳转应用权限设置接口无需拼接 want 参数多权限批量申请优化回调不会丢失单权限结果页面销毁自动终止未完成的权限申请杜绝内存泄漏。二、权限工具完整封装 utils/permission_util.etsetsimport accessToken from ohos.accessToken import common from ohos.app.ability.common import abilityAccessCtrl from ohos.abilityAccessCtrl import promptAction from ohos.promptAction import Want from ohos.app.ability.Want import UIAbility from ohos.app.ability.UIAbility import DialogUtil from ./dialog_util // 全局常用动态权限常量 export const PERMISSION { CAMERA: ohos.permission.CAMERA, READ_IMAGE: ohos.permission.READ_MEDIA_IMAGES, WRITE_MEDIA: ohos.permission.WRITE_MEDIA, NOTIFICATION: ohos.permission.NOTIFICATION_AGENT, LOCATION: ohos.permission.LOCATION } // 权限申请回调类型定义 export type PermissionCallback (granted: boolean) void class PermissionUtil { private static instance: PermissionUtil private ctx: common.UIAbilityContext | null null private atManager: abilityAccessCtrl.AbilityAccessCtrl | null null static getInstance() { if (!PermissionUtil.instance) { PermissionUtil.instance new PermissionUtil() } return PermissionUtil.instance } // 注入页面/Ability上下文 setContext(context: common.UIAbilityContext) { this.ctx context this.atManager abilityAccessCtrl.createAtManager() } // 同步校验单个权限是否已授予 checkPermission(permission: string): boolean { if (!this.ctx) return false const tokenId this.ctx.applicationInfo.accessTokenId const status accessToken.checkAccessTokenSync(tokenId, permission) return status accessToken.GrantStatus.PERMISSION_GRANTED } // 跳转系统应用权限设置页面 jumpAppSetting() { if (!this.ctx) return const want: Want { bundleName: com.ohos.settings, abilityName: com.ohos.settings.MainAbility, uri: settings://app/${this.ctx.bundleName}/permissions } this.ctx.startAbility(want) } // 申请单个动态权限 async requestPermission(permission: string, desc: string, callback: PermissionCallback) { if (!this.atManager || !this.ctx) { promptAction.showToast({ message: 上下文未初始化 }) return callback(false) } // 已授权直接执行回调 if (this.checkPermission(permission)) { return callback(true) } // 发起权限申请 const result await this.atManager.requestPermissionsFromUser(this.ctx, [permission]) const grantStatus result.authResults[0] // 1. 用户同意授权 if (grantStatus abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { return callback(true) } // 2. 永久拒绝弹窗引导跳转设置 if (result.deniedPermanent) { DialogUtil.confirm({ title: 权限提示, content: ${desc}需要对应权限才能正常使用请前往设置开启 }, () { this.jumpAppSetting() callback(false) }) } else { // 临时拒绝提示功能无法使用 promptAction.showToast({ message: 未授予权限功能无法使用 }) callback(false) } } // 批量申请多个权限相机相册 async requestMultiPermission(permissions: string[], desc: string, callback: PermissionCallback) { if (!this.atManager || !this.ctx) return callback(false) // 过滤未授权权限 const needReqList permissions.filter(p !this.checkPermission(p)) if (needReqList.length 0) return callback(true) const result await this.atManager.requestPermissionsFromUser(this.ctx, needReqList) // 判断全部权限是否授予 const allGranted result.authResults.every( s s abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED ) if (allGranted) return callback(true) // 存在永久拒绝权限引导跳转设置 if (result.deniedPermanent) { DialogUtil.confirm({ title: 权限缺失, content: ${desc}需要相关权限请前往系统设置手动开启 }, () this.jumpAppSetting()) } else { promptAction.showToast({ message: 缺少必要权限功能不可用 }) } callback(false) } // 快捷申请相机权限 reqCamera(cb: PermissionCallback) { this.requestPermission(PERMISSION.CAMERA, 拍照功能, cb) } // 快捷申请相册读写权限 reqImage(cb: PermissionCallback) { this.requestMultiPermission([PERMISSION.READ_IMAGE, PERMISSION.WRITE_MEDIA], 相册选择/保存图片, cb) } // 快捷申请通知权限 reqNotify(cb: PermissionCallback) { this.requestPermission(PERMISSION.NOTIFICATION, 消息通知推送, cb) } // 快捷申请定位权限 reqLocation(cb: PermissionCallback) { this.requestPermission(PERMISSION.LOCATION, 获取位置信息, cb) } } export default PermissionUtil.getInstance()三、业务页面实战调用3.1 拍照上传页面相机权限etsimport PermissionUtil, { PERMISSION } from ../utils/permission_util import CameraUtil from ../utils/camera_util Entry Component struct CameraPage { async aboutToAppear() { PermissionUtil.setContext(getContext(this)) } openCamera() { PermissionUtil.reqCamera((granted: boolean) { if (granted) { // 权限通过打开相机 CameraUtil.startCapture() } }) } build() { Column() { Button(打开相机拍照) .width(300) .height(48) .onClick(() this.openCamera()) } .width(100%) .height(100%) .justifyContent(Center) } }3.2 头像选择页面相册批量权限etsimport PermissionUtil from ../utils/permission_util import ImagePickerUtil from ../utils/image_picker_util // 打开相册选择图片 function pickImage() { PermissionUtil.reqImage((granted) { if (granted) { ImagePickerUtil.openAlbum() } }) }3.3 通知设置页申请通知权限etsButton(开启消息通知) .onClick(() { PermissionUtil.reqNotify((granted) { if (granted) { NotifyUtil.sendBasicNotify(1001, 通知已开启, 您将收到应用资讯推送) } }) })3.4 定位功能页面etsfunction getLocation() { PermissionUtil.reqLocation(async (granted) { if (granted) { const loc await LocationUtil.getNowLocation() console.info(当前坐标, loc) } }) }四、module.json5 权限静态声明配置动态权限必须在 module.json5 提前声明否则申请直接失败jsonrequestPermissions: [ { name: ohos.permission.CAMERA, reason: 用于拍照上传图片 }, { name: ohos.permission.READ_MEDIA_IMAGES, reason: 读取相册图片 }, { name: ohos.permission.WRITE_MEDIA, reason: 保存图片至相册 }, { name: ohos.permission.NOTIFICATION_AGENT, reason: 推送系统消息通知 }, { name: ohos.permission.LOCATION, reason: 获取地理位置信息 } ]五、API23 权限开发编码规范5.1 上下文规范页面aboutToAppear注入页面上下文PermissionUtil.setContext(getContext(this))EntryAbility onCreate 全局初始化一次全局页面可复用。5.2 权限申请时机规范用户点击功能按钮时再申请禁止页面加载自动弹窗索要权限高危功能相机、相册操作前校验权限不提前静默申请。5.3 永久拒绝分支规范用户永久拒绝权限后弹出确认弹窗引导跳转系统设置弹窗说明权限用途提升用户开启概率。5.4 批量权限规范相册读取 保存配套批量申请避免分两次弹窗打扰用户无关权限禁止批量合并申请。5.5 页面生命周期规范页面销毁无需手动取消权限申请API23 底层自动终止未完成请求权限回调内操作页面变量增加判空防止页面已销毁。六、高频报错问题解决方案问题 1调用 requestPermissionsFromUser 无授权弹窗 解决module.json5 声明对应 permission 权限名称名称完全匹配。问题 2用户勾选永久拒绝后再次申请无弹窗 解决工具内判断 deniedPermanent弹窗引导跳转应用设置页手动开启。问题 3批量申请相册权限只授予其中一个 解决使用 requestMultiPermission 批量接口同时校验读写两张媒体权限。问题 4提示上下文为空权限校验失败 解决页面 aboutToAppear 调用 setContext 注入当前页面 context。问题 5升级 API23 旧版权限代码编译报错 解决替换废弃 requestPermissions 异步接口使用 atManager 标准 API同步校验改用 checkAccessTokenSync。问题 6跳转设置页面找不到应用权限 解决want 内 bundleName 使用当前应用真实包名工具自动读取上下文 bundleName 无需手写。七、总结PermissionUtil 统一封装鸿蒙动态权限全套逻辑整合相机、相册、通知、定位高频权限快捷方法自动区分已授权 / 临时拒绝 / 永久拒绝三种状态永久拒绝场景弹窗引导跳转系统设置解决原生权限代码冗余、无引导、多权限并发错乱等工程化痛点。 完全兼容前文相机、相册、通知、上传等业务工具是所有涉及媒体、通知、定位功能项目必备底层工具适配 API23 与 HarmonyOS NEXT 课程设计、毕设完整工程架构。

相关新闻

Chat2DB 实战:从 ChatGPT 写 SQL 到专业 AI 数据库工具

Chat2DB 实战:从 ChatGPT 写 SQL 到专业 AI 数据库工具

2026/7/17 0:50:58

关键词:Chat2DB、数据库管理工具、智能问数、AI SQL、Text2SQL 很多开发者第一次体验 AI 写 SQL,通常是从 ChatGPT 这类通用大模型开始的。输入一句自然语言需求,模型很快给出 SQL 示例,看起来很高效。 但在真实团队里&#xff0…

go: Recursion Algorithm

go: Recursion Algorithm

2026/7/17 0:50:58

/* # 版权所有 2026 ©涂聚文有限公司™ # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : goLang 2024.3.6 go 26.2 # os …

AI模型评估与基准测试:从GLUE到MMLU的演进

AI模型评估与基准测试:从GLUE到MMLU的演进

2026/7/17 0:40:58

AI模型评估与基准测试:从GLUE到MMLU的演进模型评估是AI发展的基石。从早期的单一任务准确率到现代的综合能力基准,评估体系经历了根本性变革。本文将系统梳理NLP和通用AI评估基准的演进,分析各类评测的设计原理和局限性,帮助读者建…

DocsGPT开源平台:基于RAG技术的企业级智能文档助手部署指南

DocsGPT开源平台:基于RAG技术的企业级智能文档助手部署指南

2026/7/17 2:21:03

如果你正在为团队或企业构建智能助手,却苦于文档格式兼容性差、模型选择受限、部署复杂等问题,那么 DocsGPT 可能正是你需要的解决方案。这个开源项目在 GitHub 上已经获得超过 18k 星标,它不仅仅是一个简单的文档问答工具,而是一…

解决Linux开机自动加载kvm_amd模块问题

解决Linux开机自动加载kvm_amd模块问题

2026/7/17 2:21:03

1. 问题背景:为什么每次开机都要手动加载kvm_amd模块?作为一名长期使用KVM虚拟化技术的开发者,我经常遇到这样的困扰:明明已经安装了KVM相关组件,但每次重启后都需要手动执行modprobe kvm_amd才能正常使用虚拟化功能。…

RAG技术进阶:从基础检索到智能推理的42+实战方案

RAG技术进阶:从基础检索到智能推理的42+实战方案

2026/7/17 2:21:03

在尝试构建一个能够回答复杂问题的智能系统时,很多开发者都会遇到一个共同的困境:简单的关键词匹配或语义搜索往往只能找到表面相关的信息,而真正需要深入理解文档内容、进行多步推理的问题,却总是得不到满意的答案。这就是为什么…

DeepSeek MODEL1架构泄露:Engram记忆系统与MoE双稀疏度设计解析

DeepSeek MODEL1架构泄露:Engram记忆系统与MoE双稀疏度设计解析

2026/7/17 2:21:03

1. DeepSeek MODEL1架构泄露事件始末2026年1月21日,DeepSeek的FlashMLA代码库意外泄露了代号为"MODEL1"的技术文档,涉及114个文件中的28处关键引用。这次泄露之所以引发行业震动,是因为其内容与arXiv论文2601.07372描述的Engram记忆…

全志V3s GPIO驱动三套实战方案:传统字符设备、platform总线、设备树适配

全志V3s GPIO驱动三套实战方案:传统字符设备、platform总线、设备树适配

2026/7/17 2:21:03

本文还有配套的精品资源,点击获取 简介:包含全志V3s平台下三种Linux GPIO驱动实现方式的完整可运行代码包:Way1是基于字符设备的传统驱动模型,直接操作寄存器,适合理解底层硬件控制;Way2采用platform总线…

AI黑箱揭秘:可解释性技术与行业实践

AI黑箱揭秘:可解释性技术与行业实践

2026/7/17 2:11:02

1. 为什么我们需要"揭开盖子"看AI?当邻居家的小孩第一次看到自动扫地机器人工作时,他蹲下来试图掀开机器人的盖子,想看看"里面是不是藏了个小人"。这个场景完美诠释了当下大众对人工智能的认知状态——我们都知道AI能做很…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/16 0:35:09

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/16 14:29:31

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/16 14:18:17

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

Cursor终端插件生态避坑指南:23个实测低效插件黑名单,附3个自研轻量替代方案

Cursor终端插件生态避坑指南:23个实测低效插件黑名单,附3个自研轻量替代方案

2026/7/17 0:00:57

更多请点击: https://intelliparadigm.com 第一章:Cursor终端插件生态避坑指南概览 Cursor 作为基于 VS Code 内核构建的 AI 原生编辑器,其终端插件生态虽活跃,但存在兼容性断层、权限策略突变与调试链路断裂等典型风险。开发者常…

ChatGPT写作提示词效率革命:单条提示词响应质量提升3.8倍的关键变量(附可复用提示词矩阵表)

ChatGPT写作提示词效率革命:单条提示词响应质量提升3.8倍的关键变量(附可复用提示词矩阵表)

2026/7/17 0:00:57

更多请点击: https://codechina.net 第一章:ChatGPT写作提示词效率革命:单条提示词响应质量提升3.8倍的关键变量(附可复用提示词矩阵表) 提示词工程已从经验试错迈入变量驱动的科学阶段。实证研究表明,影响…

DeepSeek V4替换Codex底座模型的实践与优化

DeepSeek V4替换Codex底座模型的实践与优化

2026/7/17 0:00:57

1. 为什么选择用DeepSeek V4替换Codex的底座模型去年我在开发一个智能代码补全工具时,发现Codex的默认底座模型在复杂业务逻辑场景下表现不尽如人意。经过多次测试对比,DeepSeek V4在以下几个关键指标上展现出明显优势:代码补全准确率&#x…