HarmonyOS 6.1.1 Notification:通知发布被拆成资源、请求与系统结果后-状态模型怎样避免越级结论
验收提醒发布后,页面最容易出现的一句误导性文案是“通知已送达”。从应用调用发布接口,到用户实际看见通知、听到自定义声音,中间至少隔着资源准备、授权检查、请求返回和系统表现几层状态。把它们压成一个绿色成功标识,确实省事,却会让异常发生时没有人知道该检查哪一层。
当前项目把通知链路拆为资源层、请求层和系统结果层。资源层关心声音文件与 URI 是否准备好;请求层关心权限是否允许、发布调用是否返回;系统结果层则要求人工分别确认通知可见和声音可听。这种状态模型不会替人完成系统观察,但能避免页面用前一层的成功去伪造后一层的结论。

一、三层结果必须分别命名,不能共用“成功”
通知链路中的每一层都有自己的完成条件。资源层完成,不等于请求可发;请求返回,不等于系统界面有结果;系统界面可见,也不必然说明自定义声音已被听到。
| 层次 | 当前页面记录的状态 | 可以得出的结论 | 不能得出的结论 |
|---|---|---|---|
| 资源层 | 文件准备、源/目标字节、fileUri、sound。 | 应用已得到可用于请求的本地声音参数。 | 系统一定可以播放该声音。 |
| 授权层 | granted、denied 或授权异常。 |
当前页面已核对通知是否启用。 | 系统一定展示本轮通知。 |
| 请求层 | idle、published、failed。 |
发布调用是否返回或报错。 | 提醒已送达、已显示或已播放。 |
| 系统结果层 | 通知可见、声音可听的人工状态。 | 人工在本轮环境中观察到了什么。 | 所有设备、渠道和系统策略均相同。 |
对素材验收人员来说,这种表述并非咬文嚼字。若把资源层“文件已准备”写成“铃声已可听”,声音异常会被错误交给文件处理;若把请求层“发布已返回”写成“通知已显示”,系统设置、渠道、勿扰和用户界面观察就被跳过了。
二、资源层要先证明“参数已准备”,而不是“声音已生效”
当前项目复制内置音频到 EL1 文件区域,完成字节大小核对,再从文件路径生成 URI 并组织 sound 参数。资源层的状态应只描述这些本地事实:文件准备成功、URI 已生成、声音参数格式合规,或者其中某一步失败。
const convertedFileUri = fileUri.getUriFromPath(sandboxPath);
const sound = `uri::${convertedFileUri}`;
this.fileUriValue = convertedFileUri;
this.soundValue = sound;
this.fileState = 'EL1 文件已准备并完成大小核对';
这段代码能够证明当前页面保存了文件 URI 和请求使用的声音值,并把文件准备状态更新为完成。它不能证明通知服务读取了该值,也不能证明声音编码、音量、系统策略与设备扬声器共同满足播放条件。

因此,资源层异常和系统声音异常必须分开留痕。前者需要检查写入、大小或 URI;后者需要在请求返回后检查设备侧状态。用同一个“铃声异常”会抹平这两类不同的问题。
三、请求层只回答“发布调用发生了什么”
发布前,当前项目核对声音值和通知授权。条件不满足时,页面直接把请求状态标为失败,并说明没有调用发布;条件满足时,才组织固定 ID、通知文本和 sound 参数并等待发布调用返回。
if (!enabled) {
this.updatePublish('failed', '通知权限未授予,未调用 publish。');
return;
}
await notificationManager.publish(request);
this.updatePublish('published', '暂无错误');
这段代码能够证明两种请求层事实:通知未启用时,本轮没有调用发布;调用正常返回时,页面状态为 published。它不能证明通知中心已有新条目,也不能证明设备发出任何声音。
把“未调用 publish”和“publish 返回失败”分开,能帮助验收人员区分门禁阻断和请求异常。两种情况看起来都是“没有提醒”,下一步却不同:前者要先解决授权,后者才需要保留错误信息检查请求环境。

四、为什么发布返回后要新建一轮人工核验
当前项目只在发布调用成功返回后创建核验轮次。轮次保存发布返回时间,并把“通知可见”和“声音可听”初始化为待确认。这样做避免了两种常见错误:在根本没有成功发布时就点“已确认”,或把上一轮的观察结果混入下一轮请求。
this.createVerificationRound(
publishReturnedAt,
'publish Promise 已成功返回,等待人工分别核验通知可见与声音可听。'
);
这段代码能够证明,人工核验轮次以一次成功发布返回为前提,并记录该轮的起点。它不能证明人工已经看见通知或听到声音;两项状态仍然是待确认,必须通过后续观察更新。
对素材验收流程而言,轮次能把“哪一次发布”和“哪一次观察”绑定在一起。否则,人员可能在上午发布、下午看到一条不明来源的通知,再把它误记为上午那次自定义铃声请求的结果。

六、状态模型怎样帮助异常交接,而不是掩盖异常
当文件准备失败时,交接给文件与 URI 检查;当授权未通过时,交接给系统通知设置;当发布调用失败时,保留错误文字和本轮参数;当发布返回但人工无法判断时,交接给设备侧可见性或听觉复核。每个出口都指向缺失的那一层,而不是让人员反复执行完整流程。
尤其要避免把“新建核验轮次”误解为重新发布。当前项目允许基于既有成功发布返回创建新的人工观察轮次,这只是在会话内重新组织观察记录,不会制造新的通知请求。交接文本应如实说明这一点。

必要条件|从SDK到设备的依赖链路
本文技术点的运行链路必须按以下顺序成立:
-
SDK/API:工程使用 HarmonyOS 6.1.1(API 24),DevEco Studio 和 Hvigor 能完成
entry模块构建。
-
Kit:源码实际引入本文所需 Kit,例如
@kit.CameraKit、@kit.MapKit、@kit.NotificationKit、@kit.SpeechKit或@kit.VisionKit。 -
模块/页面:页面路由写入
main_pages.json,模块保持 Stage 配置,相关权限写入entry/src/main/module.json5。 -
权限:动态能力调用前完成 CAMERA、MICROPHONE 或其他系统授权;网络页面确认 INTERNET 已声明。
-
系统能力/硬件:设备满足本文 API 和能力要求。相机、麦克风、地图、CardRecognition 等能力缺失时必须进入降级分支。

MapKit文章在上述链路后增加服务配置:在 AppGallery Connect 创建或选择项目,绑定与工程一致的包名和签名证书,进入服务管理开通 MapKit,并按控制台要求完成应用服务凭据/授权配置;不要在文章或源码中公开 App ID、Client ID、API 密钥或私钥。完成后再验证地图初始化、搜索或事件回调。



更多推荐


所有评论(0)