HarmonyOS社交通讯应用开发 22 :权限申请机制

📅 2026/8/25 19:07:16
HarmonyOS社交通讯应用开发 22 :权限申请机制
权限申请机制引言发布页能定位、能读剪贴板、能跨设备传文件背后全靠权限支撑。HarmonyOS 的权限体系分为两类system_grant系统授权安装时静默授予用户无感知如访问网络user_grant用户授权运行时弹窗询问用户可拒绝如精确定位、读相册。开发者需要做两件事一是在module.json5里声明权限含授权理由、使用场景二是在代码里请求user_grant 权限requestPermissionsFromUser。两件事缺一不可——只声明不请求用户永远见不到授权弹窗只请求不声明直接报错。本篇以发布页为例把声明层 请求层 消费层三层权限机制讲透CommonConstants里的权限数组、BottomToolbar.requestPermissions的运行时请求、以及module.json5中 6 个权限的完整声明。知识点讲解abilityAccessCtrl 与 AtManagerabilityAccessCtrlkit.AbilityKit是权限管理模块核心入口是abilityAccessCtrl.createAtManager()返回的 AtManager应用权限管理器。最常用的方法是atManager.requestPermissionsFromUser(context,permissions)contextUIAbilityContext用于定位发起弹窗的页面上下文permissionsArrayPermissions要申请的权限名列表。返回 Promise授权完成无论同意还是拒绝后 resolve可进一步用requestPermissionsFromUser的返回值检查授权结果。注意该方法只能申请 user_grant 权限且这些权限必须已在module.json5的requestPermissions里声明。module.json5 权限声明module.json5的requestPermissions数组每项包含name权限名如ohos.permission.LOCATIONreason申请理由资源引用$string:xxx授权弹窗中展示给用户看usedScene使用场景abilities指明在哪个 Ability 使用when是inuse前台使用或always前后台均使用。系统对 user_grant 权限强制要求填写reason与usedScene否则审核或安装阶段可能被拒。定位权限的分级与联动HarmonyOS 的定位权限比较特殊分三级ohos.permission.APPROXIMATELY_LOCATION模糊定位精度约百米级ohos.permission.LOCATION精确定位ohos.permission.LOCATION_IN_BACKGROUND后台定位。系统要求申请LOCATION必须先申请APPROXIMATELY_LOCATION捆绑授权LOCATION_IN_BACKGROUND只在前台两个权限都授予后才可单独申请且usedScene.when需为inuse。本项目在module.json5中三个都声明了但运行时只弹窗申请前两个——后台定位权限在实际使用后台场景时才需申请示例工程未触发。剪贴板与媒体库权限的双轨ohos.permission.READ_PASTEBOARD读剪贴板和ohos.permission.READ_IMAGEVIDEO读公共目录图片视频也是 user_grant 权限。但工程代码巧妙地绕开了它们图库选择走系统PhotoViewPicker免权限、粘贴走PasteButton安全控件系统代读剪贴板。权限仍然声明在module.json5里属于能力声明 备而不用——保证将来用代码级接口如getPasteDataTest直接读剪贴板时不缺权限。结合本项目源码分析权限数组CommonConstants.REQUEST_PERMISSIONS文件路径entry/src/main/ets/constants/CommonConstants.ets。import{Permissions}fromkit.AbilityKit;/* * The request permission. */staticreadonlyREQUEST_PERMISSIONS:ArrayPermissions [ohos.permission.APPROXIMATELY_LOCATION,// 模糊定位ohos.permission.LOCATION// 精确定位];把权限名收敛到常量类类型用Permissions联合类型约束编译期就能发现拼写错误所有申请权限的地方引用CommonConstants.REQUEST_PERMISSIONS改权限只需动一处。运行时请求BottomToolbar.requestPermissions文件路径entry/src/main/ets/view/contentEditor/BottomToolbar.ets。requestPermissions():void{// 创建应用权限管理器letatManager abilityAccessCtrl.createAtManager();try{// 弹窗请求定位权限授权成功后开启定位监听atManager.requestPermissionsFromUser(this.context,CommonConstants.REQUEST_PERMISSIONS).then(() {LocationUtil.geolocationOn(this.getGeolocationOn);// 成功含拒绝都走到这里}).catch((err: BusinessError) { hilog.info(DOMAIN,TAG,FORMAT,RequestPermissionsFromUser failed. Cause code:${err.code}, message:${err.message}); }); }catch(err) { hilog.error(DOMAIN,TAG,FORMAT,requestPermissionsFromUser errJSON.stringify(err)); } }调用时机在aboutToAppearaboutToAppear():void{this.requestPermissions(); }这里的this.context是BottomToolbar在组件声明处通过this.getUIContext().getHostContext()拿到的 UIAbilityContext——同一个 context 贯穿了本模块的权限申请、图库选择getPhotoAccessHelper(context)与分布式文件写入writeDistributedFile(context, ...)是各类系统服务共用的身份凭证声明一次、全组件复用。三点值得注意时机前置进入发布页立刻申请授权弹窗尽早出现用户还没开始操作就有心理预期拒绝后应用仍能正常编辑内容只是位置功能不可用——这是权限失败要优雅降级的示范。Promise 语义.then()在用户做出选择后触发无论同意还是拒绝都会执行。示例工程未校验授权结果就开启定位——geolocationOn内部有 try/catch 兜底即便未授权监听注册失败也只记日志不会崩溃。真实产品应检查返回值AuthResult判断授权结果再决定后续流程。双重异常保护外层 try/catch 捕获同步异常如 context 无效.catch捕获异步异常错误都进 hilog 便于排查。声明层module.json5 的 6 个权限文件路径entry/src/main/module.json5。requestPermissions: [ {name:ohos.permission.APPROXIMATELY_LOCATION,//模糊定位reason:$string:permission_approximately_location,//弹窗展示的申请理由usedScene: {abilities: [EntryAbility],when:inuse//前台使用时 } }, {name:ohos.permission.LOCATION,//精确定位reason:$string:permission_location,usedScene: {abilities: [EntryAbility],when:inuse} }, {name:ohos.permission.LOCATION_IN_BACKGROUND,//后台定位reason:$string:permission_location_in_background,usedScene: {abilities: [EntryAbility],when:inuse} }, {name:ohos.permission.READ_PASTEBOARD,//读剪贴板reason:$string:permission_read_pasteboard,usedScene: {abilities: [EntryAbility],when:inuse} }, {name:ohos.permission.READ_IMAGEVIDEO,//读公共目录图片视频reason:$string:permission_read_imagevideo,usedScene: {abilities: [EntryAbility],when:inuse} }, {name:ohos.permission.DISTRIBUTED_DATASYNC,//分布式数据同步reason:$string:permission_distributed_datasync,usedScene: {abilities: [EntryAbility],when:inuse} } ]6 个权限与理由资源的对应关系resources/base/element/string.json中均有文案权限类型用途理由文案要点APPROXIMATELY_LOCATIONuser_grant模糊定位obtain fuzzy device location informationLOCATIONuser_grant精确定位obtain device location informationLOCATION_IN_BACKGROUNDuser_grant后台定位obtain device location information while running in the backgroundREAD_PASTEBOARDuser_grant读剪贴板read the clipboardREAD_IMAGEVIDEOuser_grant读公共图片视频reading of image or video files in the users public directoryDISTRIBUTED_DATASYNCuser_grant跨设备数据同步allow data exchange between different devicesDISTRIBUTED_DATASYNC是分布式能力的门禁接续Continue、分布式文件同步都依赖它未授权时跨设备功能不可用。它的授权同样走requestPermissionsFromUser运行时弹窗本项目在主流程中未主动申请由系统在需要时提示属示例简化处理。理由文案从声明到弹窗reason字段指向的资源文案最终会原样展示在授权弹窗里是用户判断要不要给权限的重要依据。项目在resources/base/element/string.json中为每个权限准备了独立的理由文案例如定位权限{name:permission_location,value:When loading a list of location information, Allows applications to obtain device location information}文案采用场景 能力的结构先说什么时候用加载位置信息列表时再说用到什么获取设备位置信息让用户对权限用途一目了然。同时zh_CN与en_US目录下各有对应的翻译版本系统按应用语言自动切换——权限理由的多语言维护靠的是资源文件的目录约定代码里零逻辑这也是工程把reason写成$string:xxx引用而不是硬编码字符串的原因。这里还藏着一个声明与使用对应的细节usedScene.abilities填的是EntryAbilitywhen是inuse。inuse表示应用在前台运行时使用这是定位、剪贴板这类敏感权限的推荐配置若某个权限确实需要后台使用如后台持续定位才考虑always并配合LOCATION_IN_BACKGROUND单独申请。项目把六项权限的when统一设为inuse与仅在发布页使用的实际情况一致也符合最小授权原则——声明的内容与代码的实际使用范围一一对应审计时一目了然。三层机制如何协同把发布页的权限体系串成一张图声明层module.json5 requestPermissions6个权限 reason usedScene ↓ 安装时校验user_grant 必须带 reason/usedScene 请求层 CommonConstants.REQUEST_PERMISSIONS运行时申请的精确定位模糊定位 ↓ requestPermissionsFromUser 弹窗 用户层 同意 → geolocationOn 开启定位 → 位置功能可用 拒绝 → 仅 hilog 记录 → 编辑功能照常位置列表保留默认示例声明 ≠ 请求6 个权限声明了但运行时只主动申请 2 个其余权限要么走系统选择器/安全控件规避图库、剪贴板要么在功能真正触发时由系统引导授权分布式。这是最小权限原则的实践能绕开的敏感权限就绕开绕不开的才申请。小结权限申请机制是发布页一切敏感能力的起点本项目的做法可以总结为四句话声明在 module.json56 个权限全部声明user_grant 权限补齐reason与usedScene理由文案走资源文件便于多语言请求在代码层abilityAccessCtrl.createAtManager().requestPermissionsFromUser()运行时弹窗授权成功即开启定位监听常量统一管理CommonConstants.REQUEST_PERMISSIONS集中定义权限数组一处改动全局生效能规避就规避图库选图走PhotoViewPicker、粘贴走PasteButton安全控件把敏感权限的使用面压到最小。至此模块三内容发布模块的 9 篇文章全部完成。从发布页骨架14、焦点与键盘15到本地图库16、跨设备拉取17、AddMedia 详解18、文本编辑19、底部工具栏20、定位与逆地理编码21、权限机制22一条完整的发布链路已经被逐层拆解。下一篇开始我们将进入模块四探索分布式数据与文件——看看发布的内容是如何跨越设备无缝接续的。本文引用源码entry/src/main/module.json5、entry/src/main/ets/constants/CommonConstants.ets、entry/src/main/ets/view/contentEditor/BottomToolbar.ets、entry/src/main/ets/utils/LocationUtil.ets