import { liveViewManager, LayoutType, IndicatorType, LineType } from '@kit.LiveViewKit';import { Want, wantAgent } from '@kit.AbilityKit';// 实况窗状态枚举export enum DeliveryStatus { PENDING = 0, // 待接单 ACCEPTED = 1, // 商家已接单 PICKUP = 2, // 骑手取餐 DELIVERING = 3, // 配送中 COMPLETED = 4 // 已送达}export class LiveViewUtil { // 实况窗唯一ID(自定义,全局唯一) private static readonly LIVE_VIEW_ID = 1001; // 订单号(模拟) private static readonly ORDER_ID = "DD20260507001"; // 1. 校验实况窗是否开启 static async isLiveViewEnable(): Promise<boolean> { try { return await liveViewManager.isLiveViewEnabled(); } catch (e) { console.error("校验实况窗权限失败:", e); return false; } } // 2. 构建点击跳转能力(点击卡片/胶囊跳转应用详情页) private static async buildClickAction(): Promise<Want> { const wantAgentInfo: wantAgent.WantAgentInfo = { wants: [{ bundleName: "com.example.liveviewdemo", // 替换为你的包名 abilityName: "EntryAbility", uri: `liveview://detail?orderId=${this.ORDER_ID}` } as Want], actionType: wantAgent.OperationType.START_ABILITIES, requestCode: 1002, actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] }; return await wantAgent.getWantAgent(wantAgentInfo); } // 3. 创建/更新实况窗(核心方法) static async createOrUpdateLiveView(status: DeliveryStatus, progress: number): Promise<void> { if (!await this.isLiveViewEnable()) { console.warn("用户未开启实况窗权限,无法创建"); return; } try { // 构建实况窗配置 const liveViewConfig: liveViewManager.LiveView = { id: this.LIVE_VIEW_ID, event: "DELIVERY", // 场景:即时配送 liveViewData: { // 卡片区域(通知中心/锁屏展示) primary: { title: `订单 ${this.ORDER_ID}`, content: this.getContentByStatus(status), // 动态文字内容 keepTime: 30, // 卡片展示时长(秒) clickAction: await this.buildClickAction(), // 进度条布局(配送进度可视化) richProgress: { type: 0, // 进度条类型 progress: progress, // 进度值(0-100) color: "#FF0A59F7", // 进度条主色 bgColor: "#19000000", // 背景色 indicatorType: IndicatorType.INDICATOR_TYPE_UP, // 指示器向上 indicatorIcon: "resource://rawfile/rider.png", // 指示器图标(骑手) lineType: LineType.LINE_TYPE_SOLID_LINE, // 实线进度条 nodeIcons: [ // 阶段图标(待接单→接单→取餐→送达) "resource://rawfile/icon_pending.png", "resource://rawfile/icon_accept.png", "resource://rawfile/icon_pickup.png", "resource://rawfile/icon_complete.png" ] } }, // 胶囊区域(状态栏极简提示) capsule: { type: liveViewManager.CapsuleType.CAPSULE_TYPE_TEXT, status: 1, // 胶囊状态:1=正常展示 icon: "resource://rawfile/capsule_delivery.png", // 胶囊图标 backgroundColor: "#FF0A59F7", // 胶囊背景色 title: this.getCapsuleText(status) // 胶囊文字(极简) } } }; // 启动/更新实况窗 const result = await liveViewManager.startLiveView(liveViewConfig); if (result.resultCode === 0) { console.log("实况窗创建/更新成功:", result.message); } else { console.error("实况窗操作失败:", result.message); } } catch (e) { console.error("创建实况窗异常:", e); } } // 4. 销毁实况窗(订单结束时调用) static async destroyLiveView(): Promise<void> { try { await liveViewManager.stopLiveView({ id: this.LIVE_VIEW_ID }); console.log("实况窗销毁成功"); } catch (e) { console.error("销毁实况窗异常:", e); } } // 5. 根据状态获取卡片文字内容 private static getContentByStatus(status: DeliveryStatus): Array<{ text: string, textColor?: string }> { switch (status) { case DeliveryStatus.PENDING: return [{ text: "等待商家接单..." }]; case DeliveryStatus.ACCEPTED: return [{ text: "商家已接单,准备出餐" }]; case DeliveryStatus.PICKUP: return [{ text: "骑手已取餐,正在赶往目的地" }]; case DeliveryStatus.DELIVERING: return [ { text: "配送中,距离约500米 | 预计" }, { text: "15分钟", textColor: "#FF0A59F7" }, { text: "送达" } ]; case DeliveryStatus.COMPLETED: return [{ text: "订单已送达,感谢购买!" }]; default: return [{ text: "订单状态未知" }]; } } // 6. 根据状态获取胶囊极简文字 private static getCapsuleText(status: DeliveryStatus): string { switch (status) { case DeliveryStatus.PENDING: return "待接单"; case DeliveryStatus.ACCEPTED: return "已接单"; case DeliveryStatus.PICKUP: return "已取餐"; case DeliveryStatus.DELIVERING: return "配送中"; case DeliveryStatus.COMPLETED: return "已送达"; default: return "订单更新"; } }}
import { LiveViewUtil, DeliveryStatus } from './utils/LiveViewUtil';import { CommonActions, Router } from '@kit.ArkUI';@Entry@Componentstruct Index { @State currentStatus: DeliveryStatus = DeliveryStatus.PENDING; @State progress: number = 10; // 初始进度10% @State timer: number | null = null; aboutToAppear() { // 页面加载完成后,初始化实况窗 this.initLiveView(); } aboutToDisappear() { // 页面销毁时,停止定时器 if (this.timer) clearInterval(this.timer); } // 初始化:创建实况窗 + 模拟状态自动更新 async initLiveView() { // 1. 校验权限并创建初始实况窗 await LiveViewUtil.createOrUpdateLiveView(this.currentStatus, this.progress); // 2. 模拟订单状态自动流转(每5秒更新一次) this.timer = setInterval(async () => { // 状态递进(循环) this.currentStatus = (this.currentStatus + 1) % 5; // 进度递增(0→100) this.progress = Math.min(this.progress + 20, 100); // 更新实况窗 await LiveViewUtil.createOrUpdateLiveView(this.currentStatus, this.progress); // 订单完成后,清除定时器,3秒后销毁实况窗 if (this.currentStatus === DeliveryStatus.COMPLETED) { if (this.timer) clearInterval(this.timer); setTimeout(() => { LiveViewUtil.destroyLiveView(); }, 3000); } }, 5000); } // 手动更新状态(按钮点击) async updateStatus() { this.currentStatus = (this.currentStatus + 1) % 5; this.progress = Math.min(this.progress + 20, 100); await LiveViewUtil.createOrUpdateLiveView(this.currentStatus, this.progress); } build() { Column({ space: 20, justifyContent: FlexAlign.Center }) { Text("鸿蒙实况窗演示(外卖配送)") .fontSize(20) .fontWeight(FontWeight.Bold) Text(`当前状态:${LiveViewUtil.getCapsuleText(this.currentStatus)}`) .fontSize(16) .color("#333") Text(`配送进度:${this.progress}%`) .fontSize(16) .color("#FF0A59F7") Button("手动更新订单状态") .width("80%") .height(44) .backgroundColor("#FF0A59F7") .onClick(() => this.updateStatus()) Button("销毁实况窗") .width("80%") .height(44) .backgroundColor("#FF3B30") .onClick(() => LiveViewUtil.destroyLiveView()) } .width("100%") .height("100%") .padding(20) }}