【口算王|18】HarmonyOS ArkTS 权限与隐私实战:让 module.json5、功能说明和拒绝路径一致
【口算王18】HarmonyOS ArkTS 权限与隐私实战让 module.json5、功能说明和拒绝路径一致证据边界本文依据 D:/huawei/one16-11 当前可读取源码整理本轮未执行构建、模拟器、真机权限弹窗、通知调度、TTS 网络抓包或 AGC 审核。文中对在线回退和学习提醒的描述均为源码层风险识别不代表相关能力已经验证或上线。权限合规不是在 module.json5 里“能少写就少写”。真正的工程目标是让四份事实一致应用实际功能、调用的系统 API、声明的权限、对用户和审核人员展示的说明。如果页面写着“完全离线”代码却悄悄尝试在线服务如果设置页提供“每日提醒”却没有通知调度能力如果清理数据只清界面不清磁盘都会形成审核和用户信任风险。口算王当前的权限面非常小entry 模块requestPermissions是空数组没有 INTERNET、通知、麦克风、相机、位置、联系人等声明也没有运行时请求权限的代码。题库由本地算法生成收藏、笔记、错题、进度、挑战历史和设置通过 Preferences 保存在本机。与此同时PracticePage 的文字转语音先创建离线引擎失败后会以online: 1再试SettingsPage 的“每日学习提醒”目前只保存时间没有真正注册通知或提醒任务。本文基于口算王项目D:\huawei\one16-11的真实源码复核module.json5、EntryAbility.ets、PracticePage.ets、SettingsPage.ets、UserDataManager.ets、MockBanks.ets与题库详情说明。包名com.jiaweikang.one16是本文草稿核验使用的唯一标记。项目目标和兼容 SDK 均为 HarmonyOS 6.0 系列本文方法适用于 HarmonyOS 5.0 及以上 Stage 模型应用。本文将完成六件事从 module.json5 建立实际权限清单从源码 API 反查隐含能力与数据流区分“不需要权限”“权限被拒绝”和“能力不可用”复核本地存储、清理和隐私说明边界找出提醒占位与在线 TTS 回退的一致性风险给出上架前可执行的权限隐私核对表。一、权限审计先以清单事实为准entry/src/main/module.json5 中requestPermissions:[]这意味着当前安装包没有在该模块声明系统权限。设备类型包含 phone、tablet 和 2in1但设备类型不等于权限。源码搜索也没有发现requestPermissionsFromUser()INTERNET 权限相机、麦克风、位置、联系人、日历权限通知授权请求Web 组件或普通 HTTP 客户端登录、账号、支付、广告、分析和推送 SDK。因此当前应用不存在“首次启动弹出权限框”的真实行为。二、零权限不等于零数据应用不申请敏感权限仍然会处理本地业务数据。口算王保存数据用途存储位置收藏记录收藏题目Preferences笔记记录用户题目笔记Preferences错题记录错题复习Preferences题库进度学习统计Preferences章节进度章节完成度Preferences挑战历史分数与统计Preferences提醒时间设置显示Preferences挑战时长练习配置Preferences自动下一题交互偏好Preferences这些数据没有因为“无需权限”就不属于隐私说明范围。特别是用户输入的笔记应明确仅用于本机学习记录不上传、不共享。三、题库由本地算法生成MockBanks 文件明确写着“单机题库全部题目由本地算法生成”。加减乘除、混合运算、应用题和限时题都由本地函数构造。题库详情页也向用户说明所有题目本地生成不需要联网错题会自动进入错题本方便反复巩固。这项说明与题目生成源码一致。没有远程题库下载、接口分页或账号同步。但“题目不需要联网”不应自动扩大为“应用所有能力绝不触网”因为语音引擎还需要单独核查。四、本地数据入口集中在 UserDataManagerUserDataManager 使用 Preferences 实例daily_math_drill将数组序列化为 JSON并把标量设置直接保存。页面不直接操作文件系统也没有数据库或云端 API。数据流是用户操作-UserDataManager- Preferences-AppStorage-页面刷新这种集中存储边界便于隐私审计只需核对一个服务中的键、写入和清理逻辑就能列出主要本地数据类型。五、当前没有权限拒绝路径标题中的“拒绝路径”不能机械套用。只有应用请求运行时权限用户才会选择允许或拒绝。当前 requestPermissions 为空也没有授权请求所以不存在真实的系统权限拒绝回调。当前更准确的是“能力失败路径”TTS 引擎不可用TTS 播放失败Preferences 写入失败路由参数缺失系统避免区读取失败。这些失败不等于权限拒绝。文章和用户文案应使用正确术语避免告诉用户“请授权麦克风”因为文本转语音播放不需要录音权限。六、TTS 不需要麦克风权限PracticePage 导入importtextToSpeechfromhms.ai.textToSpeech它把题目文本交给语音合成引擎播放。文本转语音是输出能力不录制用户声音因此当前没有申请 MICROPHONE 是合理的。页面点击语音提示后展示文字提示弹窗尝试准备 TTS引擎可用则播放失败则保留文字提示不阻断答题主流程。这是一条合理的能力降级链路。七、离线引擎优先是真实实现ensureTtsEngine 首先执行textToSpeech.createEngine({language:zh-CN,person: 0,online:0})online: 0表示优先使用离线引擎。成功后设置 onStart、onComplete、onStop 和 onError 监听页面显示“正在播放示例”或失败说明。如果当前设备缺少对应语音引擎方法返回 false页面显示“当前设备语音引擎不可用”。用户仍能在弹窗中阅读 audioHint 或题干。八、online:1 回退需要合规决策离线引擎创建失败后源码会再尝试textToSpeech.createEngine({language:zh-CN,person: 0,online:1})这明确表达了在线引擎意图。当前 module.json5 没有 INTERNET 权限项目也没有普通网络客户端。具体网络由应用还是系统服务承担需要依据该 TTS API 的官方说明和实机行为确认。在确认前不能同时无条件声称“所有功能完全离线”。有两个合规方向严格离线删除 online:1 回退只保留文字提示保留在线语音确认权限、数据处理和隐私披露说明发送的文本、服务提供方与网络条件。九、语音失败不会破坏核心流程toggleAudioPreview 先打开提示弹窗再在后台尽力调用 TTS。调用被 try/catch 包围即使失败也不会关闭弹窗或阻止答题。这种降级满足三个原则用户主动点击后才触发失败时有可见状态核心功能仍可通过文字完成。需要补强的是不要空 catch。至少应记录非敏感错误码便于区分引擎缺失、资源缺失和服务错误日志不应记录完整题目文本或用户笔记。十、每日提醒当前只是设置值SettingsPage 提供“每日学习提醒”可选 09:00、12:00、21:00 或关闭。selectReminder 会修改 dailyReminderTime更新显示值写入 Preferences显示“已设置”的提示。但源码中没有通知权限、提醒代理、定时任务或通知发布 API。当前行为只是保存偏好并不会在时间到达时真正提醒。因此产品文案应改为“提醒时间偏好”或暂时隐藏该入口直到实际提醒能力完成。十一、不能为占位功能提前申请通知权限即使未来计划实现提醒也不应现在先加入通知权限。权限必须与已交付功能和用户场景同步。正确顺序是明确提醒触发方式查阅 HarmonyOS 官方通知与提醒 API确认是否需要授权设计申请时机和用途说明实现允许、拒绝、不再询问、系统关闭等状态更新隐私材料再添加 module.json5 声明。当前零权限清单与“没有真实通知调度”是匹配的。十二、如果未来请求权限必须按需触发权限不应在启动页一次性请求。以未来可能的通知为例合理时机是用户主动开启提醒开关后。实现时还要把“用户动作、系统授权、界面状态”做成同一事务只有授权成功才保留开关拒绝或系统返回异常时立即回滚开关并让用户继续使用练习、错题和笔记等无权限功能。这样既避免把拒绝误判为功能故障也不会让设置页显示一个实际上无法兑现的提醒状态。请求前说明为什么需要不授权会影响什么哪些功能仍可使用如何在系统设置中重新开启。拒绝后页面应保持关闭状态不能反复弹窗、不能阻断训练也不能把普通功能包装成“必须授权”。十三、权限状态需要结构化建模若未来加入权限可以定义typePermissionState|not_requested| granted|denied|blocked| unavailable页面据此展示未请求说明用途已允许功能正常已拒绝提供降级已禁止再次询问引导系统设置设备不支持隐藏或说明。当前项目没有这套模型因为没有运行时权限它属于未来扩展建议。十四、数据保存在本机的说明有源码依据SettingsPage 的“框架”说明中写着页面采用 ArkTS 与 ArkUI 构建数据保存在本机。这与 UserDataManager 的 Preferences 实现一致。entry 的 oh-package 依赖只有本地 librarya 和 libraryb没有第三方分析、广告或网络 SDK。不过“保存在本机”还应明确生命周期数据随应用使用而更新用户可在设置页清理卸载应用后随应用数据删除当前没有账号备份与跨设备同步。十五、用户笔记是最需要谨慎对待的数据收藏、错题和进度主要由应用生成笔记包含用户自由输入。即使只存在本机也应遵循数据最小化口算练习可能由未成年人使用笔记里还可能出现姓名、班级或学习安排等用户自行填写的内容。因此默认不导出、不上传、不进入埋点和崩溃日志比事后猜测文本是否敏感更稳妥若未来增加备份或分享应重新设计明确的用户触发、范围预览和删除机制。不读取与笔记无关的设备信息不把笔记写入普通日志不上传提供删除存储异常时不在错误信息中展示全文未来增加导出或同步时重新做隐私评估。当前源码没有上传和分享笔记的能力这是可复核边界。十六、清理入口是隐私闭环的一部分SettingsPage 可以分别清除收藏笔记错题学习进度挑战历史。还提供“清除所有学习数据”的二次确认。调用 UserDataManager 的 clear 方法后把 AppStorage 中的数组设为空。这让用户无需卸载应用就能删除学习数据。需要继续验证的是持久化失败场景当前 persist 会吞掉异常页面可能显示已清空而重启后数据恢复。隐私删除必须以真正落盘成功为准。十七、隐私删除不能只清当前界面完整删除验证包括清理前记录各类数据数量执行单项或全部清理当前页面为空返回其他页面仍为空杀进程并重启数据不恢复Preferences 对应键已更新失败时向用户反馈而不是假装成功。如果未来增加缓存、数据库、文件或云端每个数据副本都要进入删除清单。十八、模块导出能力也要审计EntryAbility 的 exported 为 true并声明 HOME 实体和 home action。这是桌面启动入口的正常配置。审计时仍要确认没有额外隐蔽 Ability没有未使用的服务或 Extension外部 Want 参数经过校验导出入口不能执行敏感操作没有后台自启动、悬浮窗或跨应用干预。当前 module.json5 只列出 EntryAbility没有其他敏感扩展能力。十九、零权限有助于降低 2.19 风险App Review Guideline 2.19 关注对网络、系统机制和其他应用的滥用。当前项目没有隐藏后台任务自动启动链悬浮窗无障碍控制动态代码加载修改其他应用数据强制卸载或干扰系统未授权设备控制。这与本地口算工具的产品范围一致。后续若加入推送、网络、账号或后台提醒必须重新评估。二十、隐私材料应从代码事实生成上架材料至少应准确回答是否联网是否收集个人信息保存哪些本地数据是否使用第三方 SDK是否需要登录是否含广告或支付是否跨设备同步如何清除数据语音服务是否可能在线处理文本提醒是否真实可用。当前最稳妥的描述是题库本地生成学习记录和设置保存在本机无账号、广告和支付语音功能优先使用设备离线引擎在线回退需在发布前作出明确决策。二十一、不能把 PV、账号数据或云同步写进材料源码没有 PV 统计、点赞、收藏量上报、用户账号或云端同步。发布材料和技术文章都不能虚构这些能力。本地“收藏记录”只是用户自己的题目收藏不是平台点赞或公开社交数据。挑战历史是设备内记录也不是排行榜服务。ExamResultPage 目前展示的排名字符串不是由网络数据计算不能宣传为真实在线排名。发布核验时要把“本地功能名”和“平台运营指标”严格分开本地收藏数量只能说明设备内保存了多少道题静态排名文案也不能证明存在服务端榜单。PV、点赞、公开收藏、账号规模和云同步状态都必须来自可回读的平台或服务端数据没有真实数据时就留空。二十二、第三方依赖审计不能只看 entryentry/oh-package.json5 只依赖本地 librarya 与 libraryb但 PracticePage 直接导入系统或 HMS TTS Kit。合规审计应覆盖源码 importHAR/HSP 依赖oh-package lock原生 soSDK 初始化代码网络域名AGC 服务开关隐私政策中的 SDK 清单。“没有 npm 依赖”不等于没有平台服务依赖。TTS 应作为单独能力说明。二十三、功能说明要避免绝对化“所有题目本地生成不需要联网”是准确的题库说明。若把它改成“应用完全不联网”就会与 online:1 回退产生冲突。这种按能力拆分的表达也更便于审核复核审核人员可以分别对照题目生成、Preferences 存储和 TTS 初始化代码不必依赖一句覆盖全应用的宣传语。以后某个能力发生变化时只需同步修改对应说明、隐私材料和测试用例不会让其他离线能力一起失真。推荐把说明按功能拆开题库与训练本地运行学习数据本机保存语音提示优先使用设备语音引擎可用性取决于系统服务提醒当前仅保存偏好未提供系统通知同步当前不支持。分功能描述比一句绝对承诺更可核验。二十四、拒绝与失败文案要可行动当前语音失败文案包括当前设备语音引擎不可用语音播放失败请检查系统语音服务。它们没有错误地要求麦克风权限方向正确。还可以增强失败提示应回答三个问题哪项能力不可用、当前任务是否还能继续、用户下一步能做什么。对本应用而言TTS 失败不应中断答题也不应弹出引导用户授予无关权限的对话框保留文字展示并提供一次明确重试比笼统的“请检查权限”更符合真实故障边界。明确文字提示仍可使用提供重试避免循环创建引擎若仅离线提示下载系统离线语音资源若在线说明网络条件与隐私处理。失败文案不能暗示应用拥有实际不存在的修复能力。二十五、自动化扫描建立权限回归门槛可以在 CI 或发布脚本中检查module.json5 的 requestPermissions新增kit、ohos、hmsimportHTTP、Web、Socket、账号和推送 APICamera、Microphone、Location 等能力新增 ExtensionAbility第三方依赖和原生库隐私材料中的权限、SDK 和数据字段。任何新增能力都要求开发者更新审计表而不是等上架被拒后再补材料。二十六、权限测试矩阵当前零权限版本也要测试场景预期首次启动不弹权限框离线训练全部核心题型可用无语音引擎文字提示可用训练不中断TTS 播放失败显示失败说明可继续答题设置提醒时间仅保存显示不宣称通知已调度清空笔记当前和重启后均删除飞行模式题库、记录和练习可用系统暗色/多窗口权限和隐私入口仍可触达卸载重装本地学习数据不应保留二十七、上架前核对表[ ] requestPermissions 与实际 API 一致[ ] 不申请未使用权限[ ] 首次启动不批量索权[ ] 题库本地生成说明真实[ ] Preferences 数据类型已列入隐私说明[ ] 用户笔记不上传、不写日志[ ] 清理操作经重启验证[ ] TTS online:1 已确认去留[ ] 提醒入口与真实通知能力一致[ ] 无登录、广告、支付和分析时材料不勾选[ ] 无云同步时不宣传跨设备恢复[ ] 第三方和平台 Kit 清单已复核[ ] 安装、启动、核心流程、退出、卸载正常[ ] 审核说明能快速找到本地题库和清理入口。二十八、常见问题排查表症状可能原因处理首次启动出现权限框新依赖或模块新增声明对照 requestPermissions页面要求麦克风混淆 TTS 与录音删除错误引导提醒时间到了无通知只保存 Preferences完成真实调度或改文案宣称完全离线但语音触网online:1 回退删除或披露清空后重启数据回来持久化失败被吞掉返回删除结果隐私政策写“不存储数据”忽略本地学习记录按实际键修正说有跨设备同步把 AppStorage 当云同步明确单设备边界说有在线排名使用静态展示值删除能力宣称无第三方依赖却有 TTS只看 oh-package审计平台 Kit import用户拒绝后反复弹窗权限状态未建模按需请求并提供降级二十九、总结权限越少事实越要准确口算王当前的真实合规基础很好模块权限清单为空核心题库本地生成学习记录保存在 Preferences没有账号、广告、支付、推送和普通网络客户端语音引擎失败时保留文字提示核心训练不被阻断设置页提供数据清理入口。同样需要正视两个不一致点每日提醒目前只是配置值不能描述为已经发送系统通知TTS 在离线失败后尝试 online:1与绝对“完全离线”表述存在冲突需要在发布前选择纯离线或完成在线服务合规。权限与隐私不是一张静态表而是一条持续核验链从功能列出真实能力从 import 和 API 反查数据流与 module.json5 权限逐项比对为不可用和拒绝设计降级验证本地存储与删除同步更新隐私政策、商店材料和审核说明。只有代码、权限、页面文案和上架材料说的是同一件事零权限才真正成为产品优势。两个容易被忽略的一致性风险当前module.json5的requestPermissions为空这与工程主体采用本地题库、算法计算和 Preferences 存储的实现是吻合的。但“没有声明权限”不等于可以跳过隐私核验凡是存在在线回退、系统服务或尚未完成的设置入口都要继续追踪真实调用链。第一处是语音播报。现有练习页会优先尝试离线 TTS并在离线引擎失败后使用online: 1重试。这里不能仅凭参数名断言一定产生网络请求也不能把它写成已经验证的在线服务正确做法是继续核对所用 TTS Kit 的官方文档、运行条件、数据处理方式和真机网络行为。如果最终确认会联网应用说明、隐私政策和网络能力配置必须同步更新。第二处是“每日学习提醒”。当前设置页保存了提醒时间但现有证据没有显示通知调度或定时任务已经接入。因此文章只把它视为设置占位和后续实现风险不能宣传为已生效的提醒功能。真正实现时应重新检查是否需要通知相关能力、用户开关、拒绝后的界面反馈以及关闭提醒后是否会清理既有任务。这两个例子说明权限审计不能只搜索requestPermissions。更可靠的方式是从用户可见功能出发沿着页面事件、Service、Kit/API、配置文件和隐私文案逐层回溯并把“已实现”“待验证”“规划中”分开记录。