HarmonyOS 6.1 全场景实战|《灵犀厨房》实战(三十三):权限管理——用一套“安检系统”告别散装代码

发布时间:2026/6/11 19:07:08

HarmonyOS 6.1 全场景实战|《灵犀厨房》实战(三十三):权限管理——用一套“安检系统”告别散装代码 HarmonyOS 6.1 全场景实战《灵犀厨房》实战三十三权限管理——用一套“安检系统”告别散装代码摘要从第1篇到第30篇《灵犀厨房》已经集成了相机拍照识别食材、麦克风声控指令、通知烹饪提醒等系统能力。每一处都需要运行时权限——但之前的写法就像是每家每户自己挖井RecipeDetailPage里写一段权限检查IngredientCamera里又写一段几乎一模一样的代码……重复、散乱、改一处漏三处。今天我们新建一个PermissionHelper工具类把权限检查、请求、引导设置三项操作封装成三个静态方法用一套“统一安检系统”管住所有敏感权限。从此你的代码行数减少75%维护成本趋近于零。一、HarmonyOS 权限模型门禁卡的三个等级想象你走进一栋智能大厦normal 权限就像大厦的旋转门——任何人都可以自由通过例如访问网络INTERNET安装 App 时自动授权你甚至感觉不到它的存在。system_basic 权限像进入办公区的门禁——你需要刷一下工牌系统会弹出一个对话框问“是否允许进入”。CAMERA相机和MICROPHONE麦克风就属于这一类。用户第一次使用时系统弹出授权提示。system_core 权限像进入数据中心机房——不仅需要刷工牌还要输入动态验证码甚至需要管理员后台审批。这类权限如读取通讯录、精准定位用户需要手动到系统设置页开启。CAMERA和MICROPHONE属于system_basic级——首次使用时系统弹框询问“允许/拒绝”。如果用户勾选了“拒绝且不再询问”后续调用直接失败这时我们必须引导用户跳转到系统设置页手动开启。金句所有权限必须在module.json5中提前“声明”。声明就像在施工图纸上画好“这里要装一扇门”而运行时请求才是真正“刷卡开门”。两者缺一不可。二、PermissionHelper 设计把“散装安检”升级为“统一闸机”在重构之前每一处需要权限的页面都重复着这样 12 行“散装代码”constatManagerabilityAccessCtrl.createAtManager();constctxthis.getUIContext().getHostContext()ascommon.UIAbilityContext;consttokenIdctx.applicationInfo.accessTokenId;constgrantedatManager.checkAccessTokenSync(tokenId,ohos.permission.MICROPHONE)abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;if(!granted){constresultawaitatManager.requestPermissionsFromUser(ctx,[ohos.permission.MICROPHONE]);if(result.authResults[0]!0){/* 用户拒绝提示跳转设置 */}}每个人都在重复造轮子而且容易出错tokenId取错、回调处理不统一、跳转设置的逻辑五花八门……现在我们把这三个核心能力封装成一个静态工具类——就像大厦统一安装的“人脸识别闸机”所有楼层共用同一套系统。2.1 类图一图看懂三个方法«static»PermissionHelperisGranted(context, permission) : booleancheckAndRequest(context, permission) : PromisebooleangoToSettings(context) : void三个静态方法无需实例化同步检查权限状态即插即用检查→请求→返回结果适合按钮点击场景跳转系统设置页供用户手动开启2.2 isGranted —— 同步“查门禁”staticisGranted(context:common.UIAbilityContext,permission:string):boolean{constatManagerabilityAccessCtrl.createAtManager();returnatManager.checkAccessTokenSync(context.applicationInfo.accessTokenId,permission)abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;}为什么用同步 API权限状态本质是系统 token 中的一个标记读取它就像看一眼门禁灯——绿灯/红灯瞬间就知道。用同步方法可以避免不必要的异步等待尤其适合在页面初始化时快速判断例如决定是否显示“请授权相机”提示条。2.3 checkAndRequest —— 异步“请求放行”staticasynccheckAndRequest(context:common.UIAbilityContext,permission:string):Promiseboolean{// 先检查已有权限直接放行if(PermissionHelper.isGranted(context,permission))returntrue;// 未授权弹出系统对话框请求constatManagerabilityAccessCtrl.createAtManager();try{constresultawaitatManager.requestPermissionsFromUser(context,[permission]);// authResults[0] 0 表示用户点击“允许”returnresult.authResults.length0result.authResults[0]0;}catch(err){console.error([PermissionHelper] 请求权限失败:,JSON.stringify(err));returnfalse;}}这个方法像一个智能接待员先看你是不是已经有门禁卡isGranted有就直接放行没有就弹出系统对话框请你刷脸requestPermissionsFromUser然后告诉你“放行”还是“拒绝”。下面的流程图直观展示了整个过程✅ 已授权❌ 未授权允许拒绝拒绝且不再询问调用 checkAndRequest(ctx, ohos.permission.CAMERA)isGranted?return truerequestPermissionsFromUser()弹出系统对话框用户选择return truereturn false下次 isGranted 仍为 false调用者判断引导用户 goToSettings()2.4 goToSettings —— 跳转“后勤部”如果用户曾经拒绝且勾选了“不再询问”后续checkAndRequest将直接返回false系统不会再弹框。此时我们需要引导用户去系统设置页手动开启权限——就像门禁坏了你得去物业办公室补办一张卡。staticgoToSettings(context:common.UIAbilityContext):void{try{constwant:Want{bundleName:com.huawei.hmos.settings,// 系统设置包名abilityName:com.huawei.hmos.settings.MainAbility,uri:application_info_entry,// 跳转到应用详情页parameters:{pushParams:context.applicationInfo.name}};context.startAbility(want);}catch(err){console.error([PermissionHelper] 跳转设置失败:,JSON.stringify(err));}}设计细节goToSettings不抛异常——跳转失败比如用户正在使用低版本系统不会导致 App 崩溃最多是无法打开设置页。静默吞掉错误让主流程继续。三、使用示例从“散装12行”到“精致3行”3.1 拍照前检查相机权限第6篇食材识别场景改造前—— 重复、冗余、容易遗漏引导逻辑constatManagerabilityAccessCtrl.createAtManager();constctxthis.getUIContext().getHostContext()ascommon.UIAbilityContext;consttokenIdctx.applicationInfo.accessTokenId;constgrantedatManager.checkAccessTokenSync(tokenId,ohos.permission.CAMERA)abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;if(!granted){constresultawaitatManager.requestPermissionsFromUser(ctx,[ohos.permission.CAMERA]);if(result.authResults[0]!0){promptAction.showToast({message:需要相机权限才能拍照});return;// 往往忘了引导去设置页}}// 12 行而且丢失了引导逻辑改造后—— 3 行搞定语义清晰constctxthis.getUIContext().getHostContext()ascommon.UIAbilityContext;constgrantedawaitPermissionHelper.checkAndRequest(ctx,ohos.permission.CAMERA);if(!granted){promptAction.showToast({message:请到设置页开启相机权限});PermissionHelper.goToSettings(ctx);return;}// 继续拍照逻辑3.2 三种典型使用模式场景代码模板说明页面初始化判断决定是否显示引导条if (!PermissionHelper.isGranted(ctx, perm)) this.showHint true;同步、无弹框按钮点击请求权限如“开始录音”const ok await PermissionHelper.checkAndRequest(ctx, perm); if (ok) this.startRecord();自动弹框异步等待请求失败后引导if (!ok) { PermissionHelper.goToSettings(ctx); }跳转系统设置四、代码交付清单文件操作行数变化说明common/PermissionHelper.ets新增50三个静态方法纯工具类module.json5无需修改0权限声明相机/麦克风/通知已在之前篇章添加IngredientCamera.ets重构-9移除散装权限代码调用 HelperRecipeDetailPage.ets重构-12麦克风权限检查统一调用 Helper净减少代码约 20 行但更重要的是——未来新增任何需要权限的功能只需一行await PermissionHelper.checkAndRequest()维护成本降为 0。五、设计决策为什么这么写决策理由全静态方法权限工具无状态无需new。就像Math.max()直接调用即可isGranted用同步 API权限检查本质是读系统 token同步返回结果避免不必要的异步开销goToSettings不抛异常跳转设置失败是“锦上添花”的功能不应打断主流程。静默失败仅打日志权限声明与请求分离module.json5是编译时“备料”运行时checkAndRequest是“下锅”。各司其职不封装多权限同时请求简化设计一次只处理一个权限。调用方自行循环调用更清晰避免“部分成功”的混乱六、总结与下篇预告今天我们给《灵犀厨房》装上了一套统一权限管理“安检系统”用isGranted快速查门禁同步用checkAndRequest智能请求放行异步 自动弹框用goToSettings跳转后勤部手动开启从此任何需要相机、麦克风、通知的地方都只需 3 行代码完成权限检查。代码更干净、逻辑更统一、用户体验更一致。但这只是性能优化的前奏。下一站我们将打开 DevEco Studio 的Profiler 工具像一个“性能侦探”一样分析《灵犀厨房》的 CPU、内存、帧率瓶颈——找出那些让页面卡顿的“真凶”然后一个个优化掉。敬请期待第 32 篇 专栏持续更新中下一期我们化身“性能侦探”用 Profiler 给 App 做一次深度体检。不见不散专栏入口[《HarmonyOS6.1全场景实战》合集] 获取基线版本源码包包括第1-15篇所有代码 架构文档 Flask 后端**如果你发现本文还有任何不严谨之处欢迎随时指出我们一起共建最优质的 HarmonyOS 6.1 学习内容如果觉得有帮助请不要吝啬你的点赞 、收藏 ⭐ 和评论 !纯血鸿蒙用心造厨。我们下一篇见

相关新闻