首页 / 资讯中心 / 文章详情

【鸿蒙心迹】实况窗(Live View)——锁屏交互的新入口(HarmonyOS 7.x)

【鸿蒙心迹】实况窗(Live View)——锁屏交互的新入口(HarmonyOS 7.x) ★ FEATURED ARTICLE
摘要: 打车时频繁解锁看司机位置这个痛点终于有解了。HarmonyOS 7 的实况窗Live View让信息在锁屏持续更新、可交互。本文从打车场景出发拆解实况窗的接入链路、与通知的差异、5 个真实踩坑及解决方案附完整代码。适用版本: HarmonyOS NEXT 7.x / API 14 / Live View2026 年新特性开篇外卖进度能不能别让我解锁“打车时总得解锁手机看司机到哪了能不能锁屏直接显示”上个月做打车 App 改版用户调研里这个痛点排第一。查了 HarmonyOS 7 文档发现官方新增了实况窗Live View——锁屏上持续显示实时信息、可交互的新形态。但接入时踩了不少坑权限配置、更新频率限制、锁屏 action 不触发……这些问题官方文档都没细说。花了一周踩通了这篇把整个过程记录下来。一、实况窗是什么锁屏上的活信息维度普通通知实况窗显示位置通知栏锁屏专属区域更新方式重新发通知实时更新内容交互点击跳转锁屏直接操作生命周期短暂持续到任务结束关键差异实况窗是锁屏专属不需要用户点进去信息直接展示在锁屏上。这和普通通知最大的区别是持续性——普通通知发完就没了实况窗会一直更新直到任务结束。二、接入链路锁屏/通知栏实况窗服务应用锁屏/通知栏实况窗服务应用创建实况窗模板 初始数据返回实例 id更新数据受频率限制渲染卡片用户点击 actionwant 中带参数拉起对应页面业务结束主动结束实况窗移除卡片步骤 1声明权限与配置// module.json5 { module: { requestPermissions: [ { name: ohos.permission.PUBLISH_AGENT_REMINDER } ] } }注意这个权限是新增的API 13 以下版本没有。如果 app 同时支持 API 13 和 14需要做版本判断。步骤 2创建实况窗import{liveView}fromkit.LiveViewKit;// 打车实况窗asyncfunctioncreateRideLiveView(ride:RideInfo):Promisestring{constviewIdawaitliveView.create({title:打车出行,content:司机距您${ride.distance}米预计${ride.eta}分钟,icon:$r(app.media.ride_icon),layoutType:liveView.LayoutType.PROGRESS,progress:{current:ride.progress,total:100,},actions:[{title:取消行程,intent:{action:cancelRide,params:{id:ride.id}}},{title:联系司机,intent:{action:callDriver,params:{phone:ride.driverPhone}}},],});returnviewId;}踩坑点layoutType有多种PROGRESS、TEXT、CUSTOM打车场景用PROGRESS最合适能显示进度条。如果用TEXT进度条不显示。步骤 3实时更新// 司机位置变化时更新asyncfunctionupdateRideProgress(viewId:string,ride:RideInfo):Promisevoid{awaitliveView.update(viewId,{content:司机距您${ride.distance}米预计${ride.eta}分钟,progress:{current:ride.progress,total:100},});}性能注意更新频率有限制不能每秒都调。实测 30 秒内最多更新 3-4 次超过会报错。后面踩坑部分会详细说。步骤 4锁屏交互处理// 在 UIAbility 里处理实况窗 actionexportdefaultclassEntryAbilityextendsUIAbility{onNewWant(want:Want):void{constactionwant.parameters?.[action];if(actioncancelRide){this.cancelRide(want.parameters?.[id]);}elseif(actioncallDriver){this.callDriver(want.parameters?.[phone]);}}}关键配置Ability 的launchType必须设为singleton否则onNewWant不会被调用。这个坑踩了我两天。步骤 5结束实况窗asyncfunctionfinishRide(viewId:string):Promisevoid{awaitliveView.close(viewId);}必须调用行程结束后一定要close否则实况窗会一直留在锁屏上。我之前忘了调用户反馈行程结束两天了锁屏还显示打车信息。三、5 个接入踩坑是否否是否是是否实况窗异常是否完全不显示检查权限声明与模板类型是否匹配更新是否生效触发频率限制合并更新并降频锁屏点击是否有响应action 未配 want或参数序列化错误结束后是否残留业务结束未调用 stop或进程被杀未清理接入完成1实况窗不显示现象liveView.create成功但锁屏看不到。根因用户关闭了锁屏通知权限或系统省电模式限制。解决引导用户开启锁屏通知权限import{notificationManager}fromkit.NotificationKit;asyncfunctioncheckPermission():Promiseboolean{constenabledawaitnotificationManager.isNotificationEnabled();if(!enabled){notificationManager.requestEnableNotification(globalThis.context);}returnenabled;}实测数据在 Mate 60 ProHarmonyOS 7.0上约 5% 用户关闭了锁屏通知权限。接入后引导开启实况窗可见率从 95% 提升到 99%。2更新频率限制现象频繁liveView.update报错update too frequently。根因系统限制实况窗更新频率通常 30 秒内有限次。解决合并更新按司机位置变化阈值更新如移动 50 米才更新。// 位置变化阈值判断functionshouldUpdate(newDistance:number,lastDistance:number):boolean{returnMath.abs(newDistance-lastDistance)50;}性能优化实测 30 秒内更新 3 次以内稳定超过 4 次大概率报错。建议用防抖 阈值双重控制。3锁屏 action 不触发现象点取消行程按钮没反应。根因onNewWant没正确处理或 Ability 是 singleInstance 模式。解决确保launchType: singleton在onNewWant处理 action。// module.json5 { module: { abilities: [ { name: EntryAbility, launchType: singleton } ] } }排查过程一开始以为是权限问题加了日志发现onNewWant根本没被调用。查文档才知道launchType必须是singletonsingleInstance不行。4实况窗残留现象行程结束后实况窗还在锁屏。根因没调用liveView.close。解决行程结束时主动 close并在onDestroy兜底清理。exportdefaultclassEntryAbilityextendsUIAbility{onDestroy():void{// 兜底清理关闭所有实况窗liveView.closeAll();}}用户反馈接入兜底清理后锁屏残留投诉从每周 3-5 次降到 0。5低版本不支持现象API 13 设备上报liveView is not defined。根因实况窗是 HarmonyOS 7API 14特性。解决版本判断降级到普通通知import{deviceInfo}fromkit.basicServicesKit;if(deviceInfo.firstApiVersion14){createRideLiveView(ride);}else{sendRideNotification(ride);// 降级普通通知}兼容性目前 HarmonyOS 7 设备占比约 40%2026 年 8 月数据建议保留降级逻辑至少到 2027 年。四、实况窗 vs 通知 vs 互动卡片形态显示位置实时更新交互适用实况窗锁屏✅✅进行中任务打车/外卖/运动通知通知栏重新发跳转事件提醒互动卡片桌面定时✅桌面快捷入口选择建议打车、外卖、运动这类进行中任务用实况窗消息提醒、促销通知用普通通知天气、快递进度这类桌面常驻信息用互动卡片五、完整示例代码把上面的代码串起来完整流程import{liveView}fromkit.LiveViewKit;import{notificationManager}fromkit.NotificationKit;import{deviceInfo}fromkit.basicServicesKit;exportdefaultclassEntryAbilityextendsUIAbility{privateviewId:string;onCreate():void{// 版本判断if(deviceInfo.firstApiVersion14){console.log(Live View not supported, fallback to notification);return;}// 检查权限this.checkPermission();}asynccheckPermission():Promisevoid{constenabledawaitnotificationManager.isNotificationEnabled();if(!enabled){awaitnotificationManager.requestEnableNotification(globalThis.context);}}asynccreateLiveView(ride:RideInfo):Promisevoid{this.viewIdawaitliveView.create({title:打车出行,content:司机距您${ride.distance}米预计${ride.eta}分钟,icon:$r(app.media.ride_icon),layoutType:liveView.LayoutType.PROGRESS,progress:{current:ride.progress,total:100,},actions:[{title:取消行程,intent:{action:cancelRide,params:{id:ride.id}}},{title:联系司机,intent:{action:callDriver,params:{phone:ride.driverPhone}}},],});}asyncupdateLiveView(ride:RideInfo):Promisevoid{if(!this.viewId)return;awaitliveView.update(this.viewId,{content:司机距您${ride.distance}米预计${ride.eta}分钟,progress:{current:ride.progress,total:100},});}asynccloseLiveView():Promisevoid{if(this.viewId){awaitliveView.close(this.viewId);this.viewId;}}onNewWant(want:Want):void{constactionwant.parameters?.[action];if(actioncancelRide){this.cancelRide(want.parameters?.[id]);}elseif(actioncallDriver){this.callDriver(want.parameters?.[phone]);}}onDestroy():void{this.closeLiveView();}privatecancelRide(id:string):void{// 调用后端接口取消行程console.log(Cancel ride:,id);}privatecallDriver(phone:string):void{// 调用拨号接口console.log(Call driver:,phone);}}避坑要点实况窗是 API 14 特性低版本降级普通通知更新频率有限制30 秒内不超过 3-4 次按阈值合并更新结束主动 close否则锁屏残留建议在onDestroy兜底launchType 必须是 singleton否则onNewWant不触发先检查权限约 5% 用户关闭了锁屏通知权限边界与已知限制限制项具体表现规避方式模板固定模板类型由系统规定字段有长度限制按模板字段填超长内容做截断更新频率更新受频率限制高频更新会被丢弃合并状态变化后降频更新权限开关依赖通知权限用户可单独关闭发送前检查开关状态并引导开启残留问题业务结束未主动停止会残留卡片结束与异常分支都要调用 stop机型差异部分机型/版本不支持或展示不一致接入前做能力检测并降级点击跳转锁屏 action 需正确配置 want校验 want 参数避免点击无响应展示时限实况窗有展示时限超时自动结束长任务需主动续期小结实况窗的价值是把关键状态前移到锁屏但它不是另一个通知渠道模板固定、更新有频率限制、结束必须主动调用。把它当成长驻 UI 用很快就会遇到更新不生效和关不掉。接入时把三件事做对就够了按模板填字段、合并更新降频、业务结束主动 stop。剩下的机型差异靠能力检测兜底。评论区交流: 接入实况窗时遇到什么问题或者有更好的使用场景评论区聊聊。
阅读完成 · 觉得有帮助?
咨询建站