风险提醒的应用端调用结束后,页面最容易犯的错误,是立刻把“通知已送达”显示为成功。实际上,publish 的 Promise 返回只代表应用已经得到发布调用结果;通知中心是否可见、设备是否真的播放声音、现场人员是否看到或听到提醒,仍是不同的观察层。

当前页面工程把一次成功返回包装成一轮人工核验。该轮次同时维护通知可见性和声音可听性,两项初始均为待确认;观察者可以分别记录已确认或无法判断。这个设计看似增加了操作,实际是在风险点位提醒中保留最必要的责任边界:应用端不能替系统界面下结论,系统界面也不能替人的听觉下结论。

在这里插入图片描述

本文只讨论发布返回之后的人工核验。声音文件准备、授权检查和请求构造仍是前置条件,但不会在这里被写成发布成功的替代证据。

为什么一个“已发布”状态不够

发布返回与通知可见属于不同事实

通知服务接受请求后,应用可以记录发布时间和本地 published 状态。这说明调用没有在当前代码路径抛出错误,却不能证明通知卡片已经出现在通知中心。系统级显示可能受到通知渠道、系统策略、用户设置或设备当前状态影响,页面本身无法把这些条件全部读回。

通知可见与声音可听也不能合并

一条通知可见,声音可能因勿扰、媒体音量或系统渠道条件没有播放;声音是否听到,观察者也可能因环境噪声无法判断。若页面只提供一个“提醒已确认”按钮,后续无法定位是显示链路、声音链路还是人工观察环节缺少材料。

证据层 页面应记录的状态 可说明什么 不可说明什么
应用发布 published 与返回时间 当前调用已得到 Promise 返回 通知已可见或已播放
系统界面 visibility 观察者在本轮看到了通知 声音一定可听
听觉观察 audibility 观察者在本轮听到或无法判断声音 现场人员已响应
风险处置 风险对象、位置、责任与回执 业务是否继续处理 不能由任一通知状态推导

风险点位只是本轮核验的上下文

风险区域、设备、监测值或巡检记录可以放在提醒内容和人工观察备注中,用来解释为什么需要这次核验;它们不能替代核验结果。一个坐标被确认也不等于铃声播放,一个铃声被听到也不等于风险已解除。将空间事实与系统观察并列,才能让处置人员知道自己还缺哪一块信息。

用核验轮次隔离每一次发布返回

轮次保存的是“这一次”,不是页面总状态

每次 publish 成功返回后,页面创建新的 VerificationRound。轮次拥有自己的编号、开始时间、发布返回时间、可见性、可听性和操作事件列表。

type ManualVerificationStatus = 'pending' | 'confirmed' | 'undetermined';

interface VerificationRound {
  id: number;
  startedAt: string;
  publishReturnedAt: string;
  visibility: ManualVerificationStatus;
  audibility: ManualVerificationStatus;
  events: VerificationEvent[];
}

这段定义能说明:页面没有把所有通知结果压缩为一个全局布尔值,而是将人工证据绑定到具体发布返回。它不能说明:该轮次已经进入系统通知中心,或历史轮次已经持久化到后台。

新轮次从待确认开始

新建轮次时,两个观察字段都初始化为 pending。这能避免一个旧问题:上一轮已确认可见后,下一次发布没有重新观察,页面却仍显示“已确认”。

private createVerificationRound(publishReturnedAt: string, message: string): void {
  const startedAt = this.now();
  const round: VerificationRound = {
    id: this.nextVerificationRoundId++,
    startedAt,
    publishReturnedAt,
    visibility: 'pending',
    audibility: 'pending',
    events: [{ at: startedAt, message }]
  };
  this.verificationRounds = [round, ...this.verificationRounds];
  this.activeVerificationRoundId = round.id;
}

这段代码能说明:新的人工核验轮次只会在已有发布返回后创建,且初始不假设可见或可听。它不能说明:页面创建轮次时系统一定显示了通知;轮次是等待观察的容器,不是成功证明。

重新观察不等于重新发布

页面允许基于既有成功发布返回开启新的会话内人工核验轮次。它必须在时间线中明确记录“未重新发布通知”。这样,二次观察可以帮助排查系统状态变化,却不会被误解为已经向风险责任人再次发送了一条提醒。

对位置风险场景来说,这一点很重要。风险事件可能持续存在,但每一次重新通知都应拥有独立的发布记录;仅仅重新查看通知中心或重新听音,不能代替新发布操作。

人工结论如何只更新当前轮次

可见与可听使用两个字段

人工观察入口接收字段名和结论。字段为 visibility 时只更新通知可见状态,字段为 audibility 时只更新声音可听状态。两者互不覆盖。

private recordManualEvidence(
  field: ManualEvidenceField, status: ManualVerificationStatus
): void {
  if (this.activeVerificationRoundId === 0 || status === 'pending') {
    return;
  }
  const at = this.now();
  const label = field === 'visibility' ? '通知可见' : '声音可听';
  const conclusion = status === 'confirmed' ? '已人工确认' : '无法判断,待补系统或听觉证据';
  this.verificationRounds = this.verificationRounds.map((round: VerificationRound) => {
    if (round.id !== this.activeVerificationRoundId) {
      return round;
    }
    return {
      id: round.id,
      startedAt: round.startedAt,
      publishReturnedAt: round.publishReturnedAt,
      visibility: field === 'visibility' ? status : round.visibility,
      audibility: field === 'audibility' ? status : round.audibility,
      events: [{ at: at, message: `${label}${conclusion}` }, ...round.events]
    };
  });
  this.markOperation(`${label}人工结论已更新`);
}

这段代码能说明:人工结论只写入当前轮次,且更新一项不会覆盖另一项。它不能说明:观察结论已经被第三方确认,或观察设备处于与所有用户相同的系统设置。

“无法判断”是正确结论,不是空白

在这里插入图片描述

页面把 undeterminedpending 分开。pending 表示尚未进行观察;undetermined 表示已经尝试观察,但因系统勿扰、设备音量、环境噪声或其他条件无法给出结论。两种状态对应的下一步不同:前者等待执行观察,后者需要补充观察条件或使用其他处置渠道。

如果把无法判断直接标为失败,会误导人们去排查应用发布;如果把它标为成功,则会让风险提醒丢失人工接管出口。记录事实比强行收束状态更可靠。

没有发布返回时,观察按钮不应成为补救手段

人工核验不是“发布失败后再点一次确认”的补救入口。页面会先检查当前是否存在有效核验轮次;没有成功发布记录时,页面显示“尚无成功发布记录,不能开始人工核验”。这条门槛保证可见性和可听性总能追溯到某一次应用端返回,而不是被孤立地写入页面状态。

private hasActiveVerificationRound(): boolean {
  return this.activeVerificationRound() !== undefined;
}

if (!this.hasActiveVerificationRound()) {
  Text('尚无成功发布记录,不能开始人工核验。');
} else {
  Text(`当前轮次 #${this.activeVerificationRoundId}`);
  Text(`依据发布返回:${this.activeRoundPublishReturnedAt()}`);
}

这段代码能说明:人工观察区只在页面持有某一轮发布返回记录时开放,并且向观察者展示轮次和对应时间。它不能说明:观察者已经进入系统通知中心,或该发布返回必然产生了声音。

对风险提醒来说,这个门槛避免了另一种常见误差:现场人员知道有风险,便直接勾选“通知可见”。风险确实可能存在,但没有本轮发布返回时,这个勾选不能成为应用通知链路的证据。业务处理可以继续,通知观察必须留在它自己的证据边界内。

系统不可读条件要写在观察旁边

在这里插入图片描述

页面无法读取系统勿扰、通知渠道和媒体音量。这些不是缺少一个接口字段就可以补齐的普通页面状态,而是应用观察范围之外的系统条件。页面把它们提示在人工核验区,而不是偷偷归为通知失败。

Text('系统勿扰、通知渠道与媒体音量不可由当前应用读取。' +
  '请在系统设置中核对,再分别记录通知可见与声音可听。');

这段代码能说明:工程明确把勿扰、渠道和媒体音量列为人工观察条件,并要求分别记录可见和可听。它不能说明:当前设备的这些条件是什么;观察记录仍需要填写运行时环境,而不是凭页面默认值推断。

将核验轮次接回风险处置,而不跨层推导

三条时间线需要同时存在

风险提醒至少有三条时间线:风险何时发现或更新;应用何时准备、授权并得到发布返回;人工何时观察到可见或可听。它们可以通过风险对象和核验轮次关联,但不能相互覆盖。

风险点位或巡检记录

完成文件与授权前置

发布请求返回

创建本轮人工核验

观察通知中心可见

观察声音可听

可见结论

可听结论

记录 confirmed 或 undetermined

记录 confirmed 或 undetermined

按风险等级决定是否人工升级

图中的人工升级不是对通知 API 的补偿结论,而是风险处置的下一步。当可见或可听无法判断时,页面应把不足之处写清楚,让值守人员决定是否采用现场、电话或其他受控方式跟进。

不同组合对应不同的行动提示

可见性 可听性 正确阅读方式 可执行出口
待确认 待确认 已有发布返回,尚未观察系统 执行两项人工观察
已确认 待确认 已看到通知,声音尚未观察 继续检查声音条件
已确认 无法判断 显示证据已具备,听觉证据待补 记录设备条件并按风险等级人工接管
无法判断 已确认 听觉观察存在,通知中心未完成确认 补充系统界面证据
无法判断 无法判断 本轮有发布返回,但系统观察不足 不能写成已送达,转入人工处置

这些组合不评价风险本身是否真实,它们只说明提醒链路走到了哪里。风险是否需要升级,仍应由风险等级、责任范围和业务规则决定,不应由“声音可听”这一项单独决定。

建议的观察操作

先确认本轮是谁

开始人工观察前,先查看当前核验轮次的编号、开始时间和 publishReturnedAt。如果页面没有成功发布返回,不能直接创建或确认核验结论。这样能避免把旧通知的观察写进新风险记录。

分两次完成可见与可听

先在系统界面确认通知是否可见,再在设备条件允许时确认声音是否可听。不要因为第一项成功就跳过第二项,也不要在没有听觉条件时勾选已确认。观察时间、设备、勿扰与音量条件应成为运行记录的一部分。

保留无法判断的原因

例如“设备处于勿扰状态,未能判断声音”“通知中心当前不可访问,未能判断可见性”。原因不必伪造为系统错误,但要足以让下一位人员知道补证方向。笼统的“失败”既不能复现,也不能支持后续风险处置。

新风险、新发布、新轮次

风险对象的状态发生更新且需要再次提醒时,应重新执行发布并创建新轮次。旧轮次可以作为历史参考,但不能成为新发布的观察结论。这个规则能防止高频位置更新中出现“上一条通知已经确认,因此这一条也已确认”的错误。

按轮次做人工复核,避免状态被误读

复核从返回时间开始,而不是从按钮颜色开始

页面上的绿色、黄色或灰色状态用于帮助阅读,但它们不应成为审阅结论的唯一依据。审阅一轮风险提醒时,建议按以下顺序读取:

  1. 确认风险对象与本轮处理目标,避免将邻近位置或旧任务混入。
  2. 确认当前轮次的 publishReturnedAt 是否存在,并与页面最近操作时间对应。
  3. 分别查看 visibilityaudibility,记录其是待确认、已确认还是无法判断。
  4. 阅读该轮事件列表,确认观察结论是否由当前轮次写入。
  5. 最后记录设备、勿扰、通知渠道、媒体音量和观察环境;这些条件不由页面自动补全。

这样阅读能够把“风险需要提醒”“应用调用得到返回”“系统显示可见”“设备声音可听”拆成连续但不混淆的判断。若其中某一步缺失,正确结论是保留缺口,而不是向前借用下一步的措辞。

可见与可听的结论应该带上观察对象

人工核验的对象不是抽象的“通知功能”,而是当前设备、当前系统状态、当前核验轮次中的一条通知。记录“通知可见已确认”时,至少应能补充观察设备、通知中心位置、观察时间和当前轮次;记录“声音可听已确认”时,至少应能补充设备音量、勿扰状态是否已人工核查、观察环境和当前轮次。

这并不要求文章公开设备个人信息或业务敏感内容。它要求的是让内部运行记录可定位。发布给读者的正文可以说明应记录哪些条件,却不应捏造某台设备上的真实结果。

将人工接管写成下一步,而非成功标签

当一轮观察出现 undetermined,风险提醒不能用一个模糊的“已处理”结束。更清晰的记录是:应用端发布返回已取得;通知可见或声音可听中的哪一项无法判断;哪项系统条件尚未核查;由谁在什么时间继续观察或切换处置渠道。

人工接管的存在不说明 Notification 能力失效,反而说明页面没有用无依据的成功状态掩盖证据缺口。对于高优先级风险,这条出口能让值守人员尽早获得明确动作;对于低优先级风险,它能保留后续补证的时间和原因。

最小轮次记录表

记录项 记录目的 不能省略的原因
风险对象与区域 说明提醒为何触发 避免将观察挂到无关风险上
核验轮次与发布返回时间 绑定应用端请求 防止旧观察复用到新发布
通知可见结论 分别保留系统界面观察 不能由声音结论替代
声音可听结论 分别保留听觉观察 不能由通知中心画面替代
无法判断原因 指出待补条件 防止将未知写成失败或成功
观察环境 记录勿扰、渠道、音量等条件 页面无法自动读取这些系统状态
后续行动 明确人工接管或再次观察 防止风险处置在待补状态中中断

表中的每一项都服务于“下一位人员能否复查本轮观察”。它不要求一开始就填满所有字段;当条件不具备时,应如实记录“待补”并写出补证方向。

三类异常不要合并成一句“通知未确认”

没有轮次:先回到发布链路

页面没有当前核验轮次时,说明还没有成功发布返回可供观察。此时不能让人工观察按钮代替文件准备、授权或 publish 调用。应回看页面的文件状态、通知授权、发布状态和错误摘要,找出链路停在何处。风险对象可以进入其他处置路径,但不能生成“本轮通知可见”或“本轮声音可听”的记录。

轮次存在但仍待确认:执行一次受控观察

如果 publishReturnedAt 已存在而两个字段仍为 pending,问题不是应用发布失败,而是还没有采集系统界面或听觉证据。观察时应固定设备和当前轮次:先确认通知中心,再检查声音条件。不要同时切换系统设置、重发通知、换设备和修改风险对象,否则得到的结论无法判断属于哪个变量。

已尝试观察但无法判断:保留条件,再决定接管

undetermined 说明观察动作已经发生,但结果受到运行条件限制。记录中至少应写出无法判断的是可见性还是可听性,以及已知的系统条件,例如通知中心不可访问、勿扰状态待核对、音量条件未知或环境噪声过大。随后由风险等级决定继续补证还是采用人工联系等受控渠道;不能把“无法判断”改写成 failed,也不能用旧轮次的成功结论覆盖它。

这三类异常的共同点是都有可执行出口,但出口不相同。把它们拆开,页面和运行记录才会告诉处理者应该回到应用调用、执行系统观察,还是转入风险处置,而不是让所有问题最后都落在一句没有来源的“提醒异常”。

常见错误与排查

用 publish 返回替代人工观察

发布返回后,两个观察字段仍应保持待确认。若页面一开始就显示可见或可听已确认,说明本轮证据边界被跳过。

用一个按钮同时确认可见和可听

这样会失去问题定位能力。应分别记录两项,即使观察发生在同一时间,也要保留各自的结论。

将旧轮次的已确认状态复制到新发布

新发布意味着新的系统请求和新的观察条件。必须建立新轮次;历史状态只能作为参考,不能自动继承。

将无法判断理解为通知失败

无法判断只说明当前人工观察不足,不能反推出发布失败。应先保留发布返回和观察条件,再决定是否需要人工升级。

将人工观察当作风险解除回执

通知可见或声音可听仅说明提醒链路中的一项观察。风险解除、人员响应和现场处置需要独立的业务材料,不应由通知状态替代。

FAQ

Q:为什么发布成功后不能自动把通知可见设为已确认?

因为应用返回与系统通知中心显示是不同层。自动确认会掩盖渠道、系统设置或观察缺失问题。

Q:为什么“无法判断”要作为正式状态保存?

它表示已经进行过观察,但当前条件不能支持结论。与“待确认”相比,它能明确提示下一步需要补什么材料。

Q:可见已确认、可听无法判断,能否称为提醒已送达?

只能称“通知可见已人工确认,声音可听待补”。是否可以按业务口径称为送达,应由业务侧的明确规则决定,不能由页面自行推导。

Q:重新开始人工核验会不会重新发送通知?

不会。它基于已有的发布返回建立新的观察轮次,必须在时间线中保留“未重新发布”的说明。

Q:风险位置变更后能否继续使用原轮次?

仅查看历史观察可以引用原轮次;若位置变更触发新的提醒请求,应新建发布与核验轮次,避免把旧证据混入新风险。

必要条件|安装与配置操作手册

第1步:准备SDK和构建工具

在 DevEco Studio 的 SDK Manager 安装 HarmonyOS 6.1.1 API 24,使用项目自带 Hvigor 构建 entry 模块。

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

第2步:确认Kit引入

按本文代码检查对应 Kit:ArkWeb 使用 WebView/Download API,Camera 使用 CameraKit,ImageSource 使用图像模块,MapKit 使用 MapKit,Notification 使用 NotificationKit,AI字幕使用 SpeechKit,通行证识别使用 VisionKit。

第3步:登记模块和页面

确认页面出现在 entry/src/main/resources/base/profile/main_pages.json,并核对 module.json5 的 Stage、设备类型和权限声明。

第4步:完成设备权限

首次运行前申请本文所需权限。Camera 页面申请 CAMERA,AI字幕页面申请 MICROPHONE;权限被拒绝时先处理授权状态,不能直接创建会话或组件。

第5步:确认系统能力和硬件

在 API 24 设备或模拟器确认本文需要的摄像头、麦克风、地图服务、视觉识别或文件读取能力,能力检查通过后再执行页面操作。

在这里插入图片描述

第6步:配置 MapKit(仅MapKit文章)

在 AppGallery Connect 创建或选择项目,添加与 app.json5/工程包名一致的应用,核对签名证书指纹,进入服务管理开通 MapKit,并按控制台要求完成应用服务凭据/授权配置。只保留服务开关、包名和脱敏项目标识的截图;不得把 App ID、Client ID、API 密钥或证书私钥写入文章或源码。完成控制台配置后再验证地图初始化和检索回调。
在这里插入图片描述

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

Logo

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

更多推荐