验收提醒发布后,页面最容易出现的一句误导性文案是“通知已送达”。从应用调用发布接口,到用户实际看见通知、听到自定义声音,中间至少隔着资源准备、授权检查、请求返回和系统表现几层状态。把它们压成一个绿色成功标识,确实省事,却会让异常发生时没有人知道该检查哪一层。

当前项目把通知链路拆为资源层、请求层和系统结果层。资源层关心声音文件与 URI 是否准备好;请求层关心权限是否允许、发布调用是否返回;系统结果层则要求人工分别确认通知可见和声音可听。这种状态模型不会替人完成系统观察,但能避免页面用前一层的成功去伪造后一层的结论。

在这里插入图片描述

一、三层结果必须分别命名,不能共用“成功”

通知链路中的每一层都有自己的完成条件。资源层完成,不等于请求可发;请求返回,不等于系统界面有结果;系统界面可见,也不必然说明自定义声音已被听到。

层次 当前页面记录的状态 可以得出的结论 不能得出的结论
资源层 文件准备、源/目标字节、fileUri、sound。 应用已得到可用于请求的本地声音参数。 系统一定可以播放该声音。
授权层 granteddenied 或授权异常。 当前页面已核对通知是否启用。 系统一定展示本轮通知。
请求层 idlepublishedfailed 发布调用是否返回或报错。 提醒已送达、已显示或已播放。
系统结果层 通知可见、声音可听的人工状态。 人工在本轮环境中观察到了什么。 所有设备、渠道和系统策略均相同。

对素材验收人员来说,这种表述并非咬文嚼字。若把资源层“文件已准备”写成“铃声已可听”,声音异常会被错误交给文件处理;若把请求层“发布已返回”写成“通知已显示”,系统设置、渠道、勿扰和用户界面观察就被跳过了。

二、资源层要先证明“参数已准备”,而不是“声音已生效”

当前项目复制内置音频到 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 已成功返回,等待人工分别核验通知可见与声音可听。'
);

这段代码能够证明,人工核验轮次以一次成功发布返回为前提,并记录该轮的起点。它不能证明人工已经看见通知或听到声音;两项状态仍然是待确认,必须通过后续观察更新。

对素材验收流程而言,轮次能把“哪一次发布”和“哪一次观察”绑定在一起。否则,人员可能在上午发布、下午看到一条不明来源的通知,再把它误记为上午那次自定义铃声请求的结果。

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?

五、系统结果为什么要拆成“可见”和“可听”

通知中心可见与声音可听依赖的条件不同。前者需要在系统界面确认对应提醒是否出现;后者还受通知渠道、勿扰策略、媒体音量、设备输出和系统行为影响。即使通知可见已确认,声音仍可能无法判断;即使有人听到提示,也应核对它是否属于当前轮次,而不是其他应用或其他通知。

当前项目允许对每一项分别标记“已确认”或“无法判断”,并把操作写入当前轮次时间线。无法判断不是失败的同义词,而是承认本轮缺少足够的系统或听觉证据。它比把两项一起标绿更能支持后续补证。

人工观察 正确记录方式 不应写成
通知中心出现对应提醒 本轮通知可见已人工确认。 自定义声音已播放。
当前环境无法判断声音 声音可听待补系统或听觉证据。 铃声失效或通知未发布。
听到提示音但未核对通知来源 仅记录听觉观察待关联。 当前请求的自定义声音已确认。
两项都确认 本轮设备侧可见和可听均已有人工记录。 所有环境均可稳定复现。

在这里插入图片描述

六、状态模型怎样帮助异常交接,而不是掩盖异常

当文件准备失败时,交接给文件与 URI 检查;当授权未通过时,交接给系统通知设置;当发布调用失败时,保留错误文字和本轮参数;当发布返回但人工无法判断时,交接给设备侧可见性或听觉复核。每个出口都指向缺失的那一层,而不是让人员反复执行完整流程。

尤其要避免把“新建核验轮次”误解为重新发布。当前项目允许基于既有成功发布返回创建新的人工观察轮次,这只是在会话内重新组织观察记录,不会制造新的通知请求。交接文本应如实说明这一点。

在这里插入图片描述

必要条件|从SDK到设备的依赖链路

本文技术点的运行链路必须按以下顺序成立:

  1. SDK/API:工程使用 HarmonyOS 6.1.1(API 24),DevEco Studio 和 Hvigor 能完成 entry 模块构建。

    在这里插入图片描述

  2. Kit:源码实际引入本文所需 Kit,例如 @kit.CameraKit@kit.MapKit@kit.NotificationKit@kit.SpeechKit@kit.VisionKit

  3. 模块/页面:页面路由写入 main_pages.json,模块保持 Stage 配置,相关权限写入 entry/src/main/module.json5

  4. 权限:动态能力调用前完成 CAMERA、MICROPHONE 或其他系统授权;网络页面确认 INTERNET 已声明。

  5. 系统能力/硬件:设备满足本文 API 和能力要求。相机、麦克风、地图、CardRecognition 等能力缺失时必须进入降级分支。
    在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐