在这里插入图片描述

每日一句正能量

“活得漂亮便是拥有一种此时此地的专注力。”
漂亮不是被人看见时的光鲜,而是你沉浸于当下时的神情。一个专注洗碗的人,可以比一个心不在焉走红毯的人更“漂亮”。专注力就是灵魂的聚光灯。

前言

摘要:2026年,健康监测从"被动记录"向"主动守护"进化。HarmonyOS 6(API 23)引入的鸿蒙智能体框架2.0(HMAF 2.0)与分布式传感器能力,为开发者提供了构建"全天候健康守护"智能体的全新可能。本文将实战开发一款名为"健康守护灵"的全场景健康监测应用,展示如何利用HMAF 2.0构建支持多源数据融合、实时异常预警和个性化健康建议的AI健康分析引擎,通过悬浮导航实现健康模块快速切换,基于沉浸光感打造"健康状态即光效"的沉浸式健康体验,以及结合分布式软总线实现跨设备健康数据协同监测。


一、前言:健康监测的范式跃迁

传统健康监测应用长期受限于"数据采集→手动查看→滞后分析"的被动模式——用户需要主动打开应用查看数据,系统无法理解数据背后的健康趋势,更无法在异常发生前及时预警。当用户心率异常升高时,传统应用往往只能在用户主动查看时才显示数据,错过了最佳干预时机。

2026年,随着HMAF 2.0和分布式传感器能力的升级,鸿蒙智能体正式向主动健康守护演进。根据HDC 2026发布的信息,HarmonyOS 6将AI能力下沉至系统层,配合分布式传感器网络,实现了"数据采集→实时分析→主动预警→个性化建议"的闭环健康守护。

HarmonyOS 6(API 23)的HMAF 2.0框架支持LLM模式、工作流模式、A2A模式和OpenClaw模式四种智能体编排方式,配合分布式传感器能力,开发者可以构建真正理解用户健康状态、能主动预警和提供个性化建议的健康智能体。

本文核心亮点

  • 健康状态光效系统:6种健康状态(健康/注意/警告/危险/恢复/运动)实时映射为环境光色与动画效果
  • HMAF 2.0健康分析引擎:基于Intents Kit构建支持多源数据融合、实时异常预警和个性化建议的健康分析系统
  • 悬浮健康导航:底部悬浮页签实现健康模块快速切换(心率/血氧/睡眠/运动),支持PC端鼠标悬停预览
  • 主动异常预警:基于实时数据分析,主动触发预警光效和语音提醒
  • 跨设备健康协同:利用HarmonyOS分布式软总线,实现"手表采集+手机分析+PC展示"的跨设备健康监测

二、核心特性解析与技术选型

2.1 沉浸光感在健康监测中的价值

HarmonyOS 6的systemMaterialEffect通过模拟物理光照模型,为UI组件带来细腻的光晕与反射效果。在健康监测场景中,这种材质效果能够:

  • 健康状态可视化:用户的健康状态直接映射为环境光色,无需查看数据即可感知健康状况
  • 氛围营造:玻璃拟态的半透明层让背景光效柔和过渡,营造"被守护"的安全感
  • 异常即时预警:健康异常时红色脉冲光效,运动模式时紫色流动光效,状态切换一目了然

2.2 悬浮导航的健康适配

与传统应用不同,健康监测应用需要处理:

  • 高频模块切换:用户常在心率、血氧、睡眠、运动等模块间快速查看
  • 信息密度平衡:既要保证导航可见,又不能遮挡健康数据展示
  • PC端操作优化:支持鼠标悬停查看趋势图、右键导出健康报告

HarmonyOS 6的悬浮页签支持**强(85%)、平衡(70%)、弱(55%)**三档透明度自定义,结合PC端的自由窗口能力,可以实现"需要时出现,专注时隐退"的智能导航体验。

2.3 技术架构选型

技术模块 选用方案 说明
智能体框架 HMAF 2.0 (HarmonyOS Multi-Agent Framework 2.0) 系统级健康智能体能力
意图理解 Intents Kit 健康意图识别
传感器采集 Sensor Service Kit 心率/血氧/加速度等传感器
分布式能力 Distributed Service Kit 跨设备健康数据协同
数据存储 KV Store 本地健康数据存储
渲染引擎 Canvas + ArkUI 健康数据可视化
状态管理 AppStorage 跨组件/跨窗口状态同步
光效系统 SystemMaterialEffect + 自定义动画 健康状态光效实现

三、项目实战:"健康守护灵"架构设计

3.1 应用场景与功能规划

面向HarmonyOS PC/手机/手表的全场景健康监测应用,核心功能包括:

功能模块 技术实现 沉浸光感/HMAF应用
心率监测 Sensor Service Kit 心率异常红色脉冲光效
血氧检测 Sensor Service Kit 血氧低时橙色警示光效
睡眠分析 HMAF LLM Mode 睡眠质量光效反馈
运动追踪 Sensor Service Kit + HMAF 运动模式紫色流动光效
健康报告 HMAF Workflow Mode 健康状态综合光效
悬浮健康导航 HdsTabs + systemMaterialEffect 玻璃拟态模块切换
异常预警 HMAF + TTS Kit 异常语音提醒+光效
跨设备协同 Distributed Service Kit 手表采集+PC展示

3.2 技术架构图

在这里插入图片描述

┌─────────────────────────────────────────────────────────────┐
│                    健康守护灵 - AI健康监测智能体系统              │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │ 沉浸光感层   │  │  健康数据层  │  │ 悬浮导航层   │         │
│  │ (Ambient)   │  │  (HealthUI) │  │ (FloatNav)  │         │
│  │ 健康状态光   │  │  数据展示    │  │ 模块切换     │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │ HMAF 2.0    │  │ 传感器服务  │  │ 分布式协同   │         │
│  │ 健康分析引擎 │  │ (Sensor)   │  │ (Distributed)│         │
│  │ 异常预警     │  │ 数据采集    │  │ 跨设备同步   │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
├─────────────────────────────────────────────────────────────┤
│  多源传感器融合 (心率/血氧/加速度/陀螺仪) + 实时健康分析          │
└─────────────────────────────────────────────────────────────┘

四、环境配置与模块依赖

4.1 模块依赖配置

// entry/oh-package.json5
{
  "dependencies": {
    "@kit.UIDesignKit": "^1.0.0",
    "@kit.ArkUI": "^1.0.0",
    "@kit.AgentFrameworkKit": "^1.0.0",
    "@kit.IntentsKit": "^1.0.0",
    "@kit.DistributedServiceKit": "^1.0.0",
    "@kit.SensorServiceKit": "^1.0.0",
    "@kit.TtsKit": "^1.0.0"
  }
}

4.2 权限声明(module.json5)

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "健康守护灵 - AI健康监测智能体",
    "mainElement": "HealthAbility",
    "abilities": [
      {
        "name": "HealthAbility",
        "srcEntry": "./ets/healthability/HealthAbility.ets",
        "description": "健康监测主窗口",
        "icon": "$media:icon",
        "label": "$string:HealthAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "windowMode": "fullscreen",
        "supportWindowMode": ["fullscreen", "split", "float"]
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC"
      },
      {
        "name": "ohos.permission.SENSOR"
      },
      {
        "name": "ohos.permission.HEALTH_DATA"
      }
    ]
  }
}

五、核心组件实战

5.1 健康状态光效系统(HealthLightSystem.ets)

// entry/src/main/ets/systems/HealthLightSystem.ets

export enum HealthState {
  HEALTHY = 'healthy',
  ATTENTION = 'attention',
  WARNING = 'warning',
  DANGER = 'danger',
  RECOVERY = 'recovery',
  EXERCISE = 'exercise'
}

export interface HealthLightConfig {
  color: string;
  intensity: number;
  pulseSpeed: number;
  blurRadius: number;
  ambientColor: string;
  animationType: 'pulse' | 'flow' | 'rotate' | 'flash' | 'fade';
}

@Component
export struct HealthLightSystem {
  @State currentState: HealthState = HealthState.HEALTHY;
  @State lightIntensity: number = 0.5;
  @State pulsePhase: number = 0;

  // 健康状态-光效映射表
  private stateLightMap: Map<HealthState, HealthLightConfig> = new Map([
    [HealthState.HEALTHY, {
      color: '#00C9A7',
      intensity: 0.5,
      pulseSpeed: 3000,
      blurRadius: 100,
      ambientColor: 'rgba(0, 201, 167, 0.1)',
      animationType: 'pulse'
    }],
    [HealthState.ATTENTION, {
      color: '#FFD700',
      intensity: 0.6,
      pulseSpeed: 2000,
      blurRadius: 120,
      ambientColor: 'rgba(255, 215, 0, 0.15)',
      animationType: 'flash'
    }],
    [HealthState.WARNING, {
      color: '#FF9F1C',
      intensity: 0.7,
      pulseSpeed: 1500,
      blurRadius: 140,
      ambientColor: 'rgba(255, 159, 28, 0.2)',
      animationType: 'pulse'
    }],
    [HealthState.DANGER, {
      color: '#FF1744',
      intensity: 0.9,
      pulseSpeed: 800,
      blurRadius: 200,
      ambientColor: 'rgba(255, 23, 68, 0.3)',
      animationType: 'flash'
    }],
    [HealthState.RECOVERY, {
      color: '#4CC9F0',
      intensity: 0.4,
      pulseSpeed: 2500,
      blurRadius: 90,
      ambientColor: 'rgba(76, 201, 240, 0.1)',
      animationType: 'fade'
    }],
    [HealthState.EXERCISE, {
      color: '#7B61FF',
      intensity: 0.8,
      pulseSpeed: 1200,
      blurRadius: 160,
      ambientColor: 'rgba(123, 97, 255, 0.2)',
      animationType: 'flow'
    }]
  ]);

  aboutToAppear(): void {
    // 监听健康状态变化
    AppStorage.watch('health_state', (state: HealthState) => {
      this.currentState = state;
      this.triggerStateTransition(state);
    });
  }

  private triggerStateTransition(state: HealthState): void {
    const config = this.stateLightMap.get(state);
    if (!config) return;

    // 触发全局光效变化
    AppStorage.setOrCreate('ambient_color', config.ambientColor);
    AppStorage.setOrCreate('ambient_intensity', config.intensity);
    
    // 触发状态光效变化
    AppStorage.setOrCreate('health_glow_color', config.color);
    AppStorage.setOrCreate('health_glow_intensity', config.intensity);
    AppStorage.setOrCreate('health_pulse_speed', config.pulseSpeed);
  }

  build() {
    Stack() {
      // 底层环境光
      this.buildAmbientLight()

      // 中层健康光晕
      this.buildHealthGlow()

      // 顶层动画光效
      this.buildAnimationEffect()
    }
    .width('100%')
    .height('100%')
    .pointerEvents(PointerEvents.None)
  }

  @Builder
  buildAmbientLight(): void {
    Column()
      .width('100%')
      .height('100%')
      .backgroundColor(this.stateLightMap.get(this.currentState)?.ambientColor || 'transparent')
      .animation({
        duration: 1000,
        curve: Curve.EaseInOut
      })
  }

  @Builder
  buildHealthGlow(): void {
    Column()
      .width('100%')
      .height('100%')
      .backgroundColor(this.stateLightMap.get(this.currentState)?.color || '#FFFFFF')
      .blur(this.stateLightMap.get(this.currentState)?.blurRadius || 100)
      .opacity(this.lightIntensity)
      .animation({
        duration: 800,
        curve: Curve.EaseInOut
      })
  }

  @Builder
  buildAnimationEffect(): void {
    Column()
      .width('100%')
      .height('100%')
      .backgroundColor(this.stateLightMap.get(this.currentState)?.color || '#FFFFFF')
      .opacity(this.lightIntensity * 0.3)
      .animation({
        duration: this.stateLightMap.get(this.currentState)?.pulseSpeed || 2000,
        curve: Curve.EaseInOut,
        iterations: -1,
        playMode: PlayMode.Alternate
      })
      .scale({ x: 1.2, y: 1.2 })
      .rotate({
        angle: this.stateLightMap.get(this.currentState)?.animationType === 'rotate' ? 360 : 0,
        centerX: '50%',
        centerY: '50%'
      })
      .animation({
        duration: this.stateLightMap.get(this.currentState)?.animationType === 'rotate' ? 3000 : 0,
        curve: Curve.Linear,
        iterations: -1
      })
  }
}

代码亮点

  • 6种健康状态光效:健康(青绿呼吸)、注意(金色闪烁)、警告(橙色脉冲)、危险(红色急促)、恢复(蓝色渐变)、运动(紫色流动)
  • 三层光效架构:环境光层 → 健康光晕层 → 动画光效层,层次分明
  • 平滑过渡动画:状态切换时800-1000ms的缓动动画,避免光效突变造成视觉割裂
  • 无限循环动画:根据健康状态设置不同的脉冲速度和动画类型

5.2 HMAF 2.0健康分析引擎(HealthAnalysisEngine.ets)

// entry/src/main/ets/engine/HealthAnalysisEngine.ets
import { hmaf } from '@kit.AgentFrameworkKit';
import { intents } from '@kit.IntentsKit';

export interface HealthData {
  heartRate: number;
  spo2: number;
  sleepScore: number;
  steps: number;
  calories: number;
  stressLevel: number;
  timestamp: number;
}

export interface HealthTrend {
  metric: string;
  values: number[];
  timestamps: number[];
  trend: 'up' | 'down' | 'stable';
  anomaly: boolean;
}

export interface HealthAdvice {
  type: string;
  title: string;
  content: string;
  priority: number;
  actions: string[];
}

export class HealthAnalysisEngine {
  private session: hmaf.AgentSession | null = null;
  private intentEngine: intents.IntentEngine | null = null;
  private healthHistory: Map<string, HealthData[]> = new Map();
  private anomalyThresholds: Map<string, { min: number; max: number }> = new Map();

  async initialize(): Promise<void> {
    // 创建HMAF 2.0智能体会话
    this.session = await hmaf.createAgentSession({
      mode: hmaf.AgentMode.LLM,
      enableDistributed: true,
      maxConcurrentAgents: 10,
      contextMemory: true
    });

    // 创建意图引擎
    this.intentEngine = await intents.createIntentEngine({
      supportedDomains: ['health.monitor', 'health.advice', 'health.alert'],
      confidenceThreshold: 0.8,
      enableMultiTurn: true
    });

    // 初始化异常阈值
    this.initializeThresholds();
  }

  private initializeThresholds(): void {
    this.anomalyThresholds.set('heartRate', { min: 60, max: 100 });
    this.anomalyThresholds.set('spo2', { min: 95, max: 100 });
    this.anomalyThresholds.set('sleepScore', { min: 70, max: 100 });
    this.anomalyThresholds.set('stressLevel', { min: 0, max: 70 });
  }

  // 分析健康数据
  async analyzeHealthData(
    userId: string, 
    data: HealthData
  ): Promise<HealthState> {
    // 保存数据
    const history = this.healthHistory.get(userId) || [];
    history.push(data);
    if (history.length > 100) history.shift();
    this.healthHistory.set(userId, history);

    // 检测异常
    const anomalies = this.detectAnomalies(data);
    
    if (anomalies.length > 0) {
      // 触发异常预警
      const highestPriority = anomalies.sort((a, b) => b.priority - a.priority)[0];
      
      if (highestPriority.priority >= 3) {
        AppStorage.setOrCreate('health_state', HealthState.DANGER);
        await this.triggerAlert(userId, highestPriority);
        return HealthState.DANGER;
      } else if (highestPriority.priority >= 2) {
        AppStorage.setOrCreate('health_state', HealthState.WARNING);
        return HealthState.WARNING;
      } else {
        AppStorage.setOrCreate('health_state', HealthState.ATTENTION);
        return HealthState.ATTENTION;
      }
    }

    // 检查运动状态
    if (data.steps > 100 || data.calories > 50) {
      AppStorage.setOrCreate('health_state', HealthState.EXERCISE);
      return HealthState.EXERCISE;
    }

    // 正常状态
    AppStorage.setOrCreate('health_state', HealthState.HEALTHY);
    return HealthState.HEALTHY;
  }

  // 检测异常
  private detectAnomalies(data: HealthData): Array<{ metric: string; value: number; priority: number }> {
    const anomalies: Array<{ metric: string; value: number; priority: number }> = [];

    // 心率异常
    const hrThreshold = this.anomalyThresholds.get('heartRate');
    if (hrThreshold && (data.heartRate < hrThreshold.min || data.heartRate > hrThreshold.max)) {
      anomalies.push({
        metric: 'heartRate',
        value: data.heartRate,
        priority: data.heartRate > 120 || data.heartRate < 50 ? 3 : 2
      });
    }

    // 血氧异常
    const spo2Threshold = this.anomalyThresholds.get('spo2');
    if (spo2Threshold && data.spo2 < spo2Threshold.min) {
      anomalies.push({
        metric: 'spo2',
        value: data.spo2,
        priority: data.spo2 < 90 ? 3 : 2
      });
    }

    // 睡眠评分异常
    const sleepThreshold = this.anomalyThresholds.get('sleepScore');
    if (sleepThreshold && data.sleepScore < sleepThreshold.min) {
      anomalies.push({
        metric: 'sleepScore',
        value: data.sleepScore,
        priority: 1
      });
    }

    // 压力水平异常
    const stressThreshold = this.anomalyThresholds.get('stressLevel');
    if (stressThreshold && data.stressLevel > stressThreshold.max) {
      anomalies.push({
        metric: 'stressLevel',
        value: data.stressLevel,
        priority: data.stressLevel > 90 ? 3 : 2
      });
    }

    return anomalies;
  }

  // 触发异常预警
  private async triggerAlert(
    userId: string, 
    anomaly: { metric: string; value: number; priority: number }
  ): Promise<void> {
    // 语音预警
    const ttsEngine = AppStorage.get('tts_engine') as tts.Engine;
    if (ttsEngine) {
      await ttsEngine.speak(`注意,您的${this.getMetricLabel(anomaly.metric)}异常,当前值为${anomaly.value},请关注。`);
    }

    // 推送通知
    AppStorage.setOrCreate('health_alert', {
      metric: anomaly.metric,
      value: anomaly.value,
      priority: anomaly.priority,
      timestamp: Date.now()
    });
  }

  // 生成健康建议
  async generateHealthAdvice(userId: string): Promise<HealthAdvice[]> {
    const history = this.healthHistory.get(userId) || [];
    if (history.length < 7) return [];

    // 分析趋势
    const trends = this.analyzeTrends(history);
    
    // 生成建议
    const advices: HealthAdvice[] = [];
    
    trends.forEach(trend => {
      if (trend.anomaly) {
        advices.push({
          type: 'warning',
          title: `${this.getMetricLabel(trend.metric)}趋势异常`,
          content: `您的${this.getMetricLabel(trend.metric)}呈现${trend.trend === 'up' ? '上升' : '下降'}趋势,建议关注。`,
          priority: 3,
          actions: ['查看详情', '咨询医生']
        });
      }
    });

    // 基于HMAF生成个性化建议
    const prompt = `基于用户最近7天的健康数据,生成3条个性化健康建议。
    数据:${JSON.stringify(history.slice(-7))}`;
    
    const result = await this.session?.sendTask({
      targetAgent: 'health_advisor',
      taskType: hmaf.TaskType.HEALTH_ADVICE,
      payload: { prompt }
    });

    if (result?.advices) {
      advices.push(...result.advices);
    }

    return advices.sort((a, b) => b.priority - a.priority);
  }

  // 分析趋势
  private analyzeTrends(history: HealthData[]): HealthTrend[] {
    const trends: HealthTrend[] = [];
    
    const metrics = ['heartRate', 'spo2', 'sleepScore', 'stressLevel'];
    
    metrics.forEach(metric => {
      const values = history.map(h => h[metric as keyof HealthData] as number);
      const timestamps = history.map(h => h.timestamp);
      
      // 简单线性回归判断趋势
      const n = values.length;
      const sumX = timestamps.reduce((a, b) => a + b, 0);
      const sumY = values.reduce((a, b) => a + b, 0);
      const sumXY = timestamps.reduce((sum, t, i) => sum + t * values[i], 0);
      const sumX2 = timestamps.reduce((sum, t) => sum + t * t, 0);
      
      const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
      
      let trend: 'up' | 'down' | 'stable' = 'stable';
      if (slope > 0.1) trend = 'up';
      else if (slope < -0.1) trend = 'down';
      
      // 检测异常趋势
      const latest = values.slice(-3);
      const avg = values.reduce((a, b) => a + b, 0) / values.length;
      const stdDev = Math.sqrt(values.reduce((sum, v) => sum + Math.pow(v - avg, 2), 0) / values.length);
      const anomaly = latest.some(v => Math.abs(v - avg) > 2 * stdDev);
      
      trends.push({
        metric,
        values,
        timestamps,
        trend,
        anomaly
      });
    });
    
    return trends;
  }

  private getMetricLabel(metric: string): string {
    const labels: Map<string, string> = new Map([
      ['heartRate', '心率'],
      ['spo2', '血氧'],
      ['sleepScore', '睡眠评分'],
      ['stressLevel', '压力水平'],
      ['steps', '步数'],
      ['calories', '卡路里']
    ]);
    return labels.get(metric) || metric;
  }
}

代码亮点

  • 多源数据融合:整合心率、血氧、睡眠、步数、卡路里、压力等多维度健康数据
  • 实时异常检测:基于预设阈值实时检测异常,支持三级优先级(注意/警告/危险)
  • 趋势分析:使用线性回归分析健康趋势,提前预警潜在风险
  • 主动语音预警:异常时自动触发TTS语音提醒,无需用户主动查看

5.3 悬浮健康导航(HealthFloatNav.ets)

// entry/src/main/ets/components/HealthFloatNav.ets
import { HdsTabs, HdsTabItem } from '@kit.UIDesignKit';

export interface HealthModule {
  id: string;
  name: string;
  icon: Resource;
  metric: string;
  unit: string;
  normalRange: string;
  currentValue: number;
  state: HealthState;
}

@Component
export struct HealthFloatNav {
  @State modules: HealthModule[] = [];
  @State selectedIndex: number = 0;
  @State transparency: number = 0.70;
  @State isExpanded: boolean = false;
  @State avoidHeight: number = 0;

  // 状态光色映射
  private stateColors: Map<HealthState, string> = new Map([
    [HealthState.HEALTHY, '#00C9A7'],
    [HealthState.ATTENTION, '#FFD700'],
    [HealthState.WARNING, '#FF9F1C'],
    [HealthState.DANGER, '#FF1744'],
    [HealthState.RECOVERY, '#4CC9F0'],
    [HealthState.EXERCISE, '#7B61FF']
  ]);

  aboutToAppear(): void {
    // 初始化健康模块
    this.modules = [
      {
        id: 'heartRate',
        name: '心率',
        icon: $r('app.media.ic_heart'),
        metric: 'heartRate',
        unit: 'bpm',
        normalRange: '60-100',
        currentValue: 72,
        state: HealthState.HEALTHY
      },
      {
        id: 'spo2',
        name: '血氧',
        icon: $r('app.media.ic_spo2'),
        metric: 'spo2',
        unit: '%',
        normalRange: '95-100',
        currentValue: 98,
        state: HealthState.HEALTHY
      },
      {
        id: 'sleep',
        name: '睡眠',
        icon: $r('app.media.ic_sleep'),
        metric: 'sleepScore',
        unit: '分',
        normalRange: '70-100',
        currentValue: 85,
        state: HealthState.HEALTHY
      },
      {
        id: 'exercise',
        name: '运动',
        icon: $r('app.media.ic_exercise'),
        metric: 'steps',
        unit: '步',
        normalRange: '10000+',
        currentValue: 6500,
        state: HealthState.HEALTHY
      }
    ];

    // 获取底部安全区高度
    let windowInstance = window.getLastWindow(getContext(this));
    windowInstance.then((win) => {
      let avoidArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
      this.avoidHeight = avoidArea.bottomRect.height;
    });

    // 监听健康状态变化
    AppStorage.watch('health_state', (state: HealthState) => {
      if (this.selectedIndex >= 0 && this.selectedIndex < this.modules.length) {
        this.modules[this.selectedIndex].state = state;
      }
    });
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      Column() {
        // 模块信息展开面板(悬停时显示)
        if (this.isExpanded && this.selectedIndex >= 0) {
          this.buildModuleDetailPanel()
        }

        // 悬浮模块页签
        HdsTabs({
          items: this.modules.map((module, index) => ({
            icon: module.icon,
            label: module.name,
            badge: module.state !== HealthState.HEALTHY ? 1 : undefined,
            customStyle: {
              backgroundColor: this.selectedIndex === index 
                ? this.stateColors.get(module.state) 
                : 'transparent',
              borderColor: this.selectedIndex === index 
                ? this.stateColors.get(module.state) 
                : 'rgba(255,255,255,0.2)'
            }
          })),
          selectedIndex: this.selectedIndex,
          onSelect: (index: number) => {
            this.selectedIndex = index;
            AppStorage.setOrCreate('selected_module', this.modules[index]);
            // 触发对应模块的光效
            AppStorage.setOrCreate('health_state', this.modules[index].state);
          },
          onHover: (index: number) => {
            this.isExpanded = true;
            if (index >= 0) {
              AppStorage.setOrCreate('hover_module', this.modules[index]);
            }
          },
          backgroundStyle: {
            blurStyle: BlurStyle.REGULAR,
            backgroundColor: `rgba(20, 20, 30, ${this.transparency})`,
            borderRadius: 24
          },
          indicatorStyle: {
            color: this.stateColors.get(this.modules[this.selectedIndex]?.state) || '#00C9A7',
            height: 3,
            width: 24,
            borderRadius: 2
          }
        })
        .height(64)
        .width('96%')
        .margin({ bottom: 12 })
      }
      .width('100%')
      .padding({ bottom: this.avoidHeight + 12 })
    }
    .width('100%')
    .height('100%')
    .pointerEvents(PointerEvents.BoxNone)
  }

  @Builder
  buildModuleDetailPanel(): void {
    Column({ space: 8 }) {
      // 模块图标与名称
      Row({ space: 12 }) {
        Stack() {
          Image(this.modules[this.selectedIndex].icon)
            .width(48)
            .height(48)
            .borderRadius(24)
            .border({
              width: 2,
              color: this.stateColors.get(this.modules[this.selectedIndex].state) || '#FFFFFF'
            })
            .shadow({
              radius: 10,
              color: this.stateColors.get(this.modules[this.selectedIndex].state) || '#FFFFFF'
            })
          
          // 状态指示点
          Circle()
            .width(12)
            .height(12)
            .fill(this.stateColors.get(this.modules[this.selectedIndex].state) || '#FFFFFF')
            .position({ x: 36, y: 36 })
            .shadow({
              radius: 6,
              color: this.stateColors.get(this.modules[this.selectedIndex].state) || '#FFFFFF'
            })
            .animation({
              duration: 1000,
              curve: Curve.EaseInOut,
              iterations: -1,
              playMode: PlayMode.Alternate
            })
            .scale({ x: 1.3, y: 1.3 })
        }

        Column({ space: 4 }) {
          Text(this.modules[this.selectedIndex].name)
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
            .fontColor('#FFFFFF')
          
          Text(`${this.modules[this.selectedIndex].currentValue}${this.modules[this.selectedIndex].unit}`)
            .fontSize(14)
            .fontColor(this.stateColors.get(this.modules[this.selectedIndex].state) || '#FFFFFF')
        }
        .alignItems(HorizontalAlign.Start)

        Blank()

        // 正常范围提示
        Text(`正常: ${this.modules[this.selectedIndex].normalRange}`)
          .fontSize(11)
          .fontColor('rgba(255,255,255,0.5)')
      }
      .width('100%')
      .padding(12)
    }
    .width('96%')
    .backgroundColor('rgba(20, 20, 30, 0.9)')
    .borderRadius(16)
    .border({
      width: 1,
      color: this.stateColors.get(this.modules[this.selectedIndex].state) || 'rgba(255,255,255,0.1)'
    })
    .margin({ bottom: 8 })
    .animation({
      duration: 200,
      curve: Curve.EaseInOut
    })
  }
}

代码亮点

  • 状态感知模块页签:每个模块的页签边框和指示器颜色随其健康状态动态变化
  • 异常徽章提示:非健康状态时显示数字徽章,提醒用户关注
  • 悬停详情面板:PC端鼠标悬停时展开模块详细信息(当前值/正常范围/状态)
  • 状态呼吸灯:模块头像右下角的状态指示点持续脉冲呼吸

5.4 健康数据可视化(HealthDataChart.ets)

// entry/src/main/ets/components/HealthDataChart.ets
import { HealthData } from '../engine/HealthAnalysisEngine';

@Component
export struct HealthDataChart {
  @Prop data: HealthData[];
  @Prop metric: string;
  @State chartColor: string = '#00C9A7';

  // 指标颜色映射
  private metricColors: Map<string, string> = new Map([
    ['heartRate', '#FF1744'],
    ['spo2', '#4CC9F0'],
    ['sleepScore', '#7B61FF'],
    ['steps', '#00C9A7'],
    ['calories', '#FF9F1C'],
    ['stressLevel', '#FF6B9D']
  ]);

  aboutToAppear(): void {
    this.chartColor = this.metricColors.get(this.metric) || '#00C9A7';
  }

  build() {
    Column() {
      Text(this.getMetricLabel(this.metric))
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .margin({ bottom: 12 })

      // 趋势图
      Canvas(this.chartContext)
        .width('100%')
        .height(200)
        .onReady((context) => {
          this.drawTrendChart(context);
        })

      // 统计信息
      Row({ space: 16 }) {
        Column() {
          Text('平均值')
            .fontSize(11)
            .fontColor('rgba(255,255,255,0.5)')
          
          Text(`${this.calculateAverage().toFixed(1)}`)
            .fontSize(18)
            .fontColor('#FFFFFF')
            .fontWeight(FontWeight.Bold)
        }

        Column() {
          Text('最高值')
            .fontSize(11)
            .fontColor('rgba(255,255,255,0.5)')
          
          Text(`${this.calculateMax().toFixed(1)}`)
            .fontSize(18)
            .fontColor(this.chartColor)
            .fontWeight(FontWeight.Bold)
        }

        Column() {
          Text('最低值')
            .fontSize(11)
            .fontColor('rgba(255,255,255,0.5)')
          
          Text(`${this.calculateMin().toFixed(1)}`)
            .fontSize(18)
            .fontColor('#4CC9F0')
            .fontWeight(FontWeight.Bold)
        }
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
      .margin({ top: 12 })
    }
    .width('100%')
    .padding(16)
    .backgroundColor('rgba(255,255,255,0.03)')
    .borderRadius(16)
  }

  private drawTrendChart(context: CanvasRenderingContext2D): void {
    const width = 400;
    const height = 200;
    const padding = 40;
    
    const values = this.data.map(d => d[this.metric as keyof HealthData] as number);
    const maxValue = Math.max(...values) * 1.2;
    const minValue = Math.min(...values) * 0.8;
    
    // 绘制网格
    context.strokeStyle = 'rgba(255,255,255,0.1)';
    context.lineWidth = 1;
    for (let i = 0; i <= 5; i++) {
      const y = padding + (height - 2 * padding) * i / 5;
      context.beginPath();
      context.moveTo(padding, y);
      context.lineTo(width - padding, y);
      context.stroke();
    }
    
    // 绘制数据线
    context.beginPath();
    context.strokeStyle = this.chartColor;
    context.lineWidth = 2;
    
    values.forEach((value, index) => {
      const x = padding + (width - 2 * padding) * index / (values.length - 1);
      const y = padding + (height - 2 * padding) * (1 - (value - minValue) / (maxValue - minValue));
      
      if (index === 0) {
        context.moveTo(x, y);
      } else {
        context.lineTo(x, y);
      }
    });
    context.stroke();
    
    // 绘制数据点
    values.forEach((value, index) => {
      const x = padding + (width - 2 * padding) * index / (values.length - 1);
      const y = padding + (height - 2 * padding) * (1 - (value - minValue) / (maxValue - minValue));
      
      context.beginPath();
      context.arc(x, y, 4, 0, 2 * Math.PI);
      context.fillStyle = this.chartColor;
      context.fill();
      context.strokeStyle = '#FFFFFF';
      context.lineWidth = 2;
      context.stroke();
    });
  }

  private calculateAverage(): number {
    const values = this.data.map(d => d[this.metric as keyof HealthData] as number);
    return values.reduce((a, b) => a + b, 0) / values.length;
  }

  private calculateMax(): number {
    const values = this.data.map(d => d[this.metric as keyof HealthData] as number);
    return Math.max(...values);
  }

  private calculateMin(): number {
    const values = this.data.map(d => d[this.metric as keyof HealthData] as number);
    return Math.min(...values);
  }

  private getMetricLabel(metric: string): string {
    const labels: Map<string, string> = new Map([
      ['heartRate', '心率趋势'],
      ['spo2', '血氧趋势'],
      ['sleepScore', '睡眠评分趋势'],
      ['steps', '步数趋势'],
      ['calories', '卡路里趋势'],
      ['stressLevel', '压力水平趋势']
    ]);
    return labels.get(metric) || '趋势';
  }
}

5.5 跨设备健康协同(DistributedHealthSync.ets)

// entry/src/main/ets/distributed/DistributedHealthSync.ets
import { distributedService } from '@kit.DistributedServiceKit';

export class DistributedHealthSync {
  private manager: distributedService.Manager | null = null;
  private remoteDevices: distributedService.DeviceInfo[] = [];
  private watchDevice: string | null = null;

  async initialize(): Promise<void> {
    this.manager = distributedService.createManager();
    
    // 初始化分布式服务
    await this.manager.init({
      deviceType: ['phone', 'tablet', 'pc', 'watch'],
      serviceName: 'health_guardian_sync',
      abilityName: 'HealthDistributedAbility'
    });

    // 监听设备变化
    this.manager.on('deviceStateChange', (deviceInfo, state) => {
      if (state === 'online') {
        this.remoteDevices.push(deviceInfo);
        if (deviceInfo.deviceType === 'watch') {
          this.watchDevice = deviceInfo.deviceId;
        }
      } else if (state === 'offline') {
        this.remoteDevices = this.remoteDevices.filter(d => d.deviceId !== deviceInfo.deviceId);
        if (this.watchDevice === deviceInfo.deviceId) {
          this.watchDevice = null;
        }
      }
    });
  }

  // 从手表同步健康数据
  async syncFromWatch(): Promise<HealthData | null> {
    if (!this.watchDevice) return null;

    const result = await this.manager?.sendMessage({
      targetDeviceId: this.watchDevice,
      message: {
        type: 'get_health_data',
        timestamp: Date.now()
      },
      expectResponse: true,
      timeout: 5000
    });

    return result?.payload as HealthData;
  }

  // 同步健康数据到PC展示
  async syncToPC(data: HealthData): Promise<void> {
    const pcDevice = this.remoteDevices.find(d => d.deviceType === 'pc');
    if (!pcDevice) return;

    await this.manager?.sendMessage({
      targetDeviceId: pcDevice.deviceId,
      message: {
        type: 'health_data_update',
        data,
        timestamp: Date.now()
      }
    });
  }

  // 同步预警到所有设备
  async broadcastAlert(alert: HealthAlert): Promise<void> {
    for (const device of this.remoteDevices) {
      await this.manager?.sendMessage({
        targetDeviceId: device.deviceId,
        message: {
          type: 'health_alert',
          alert,
          timestamp: Date.now()
        }
      });
    }
  }

  // 获取远程设备上的健康界面
  async getRemoteHealthUI(deviceId: string): Promise<void> {
    await this.manager?.sendMessage({
      targetDeviceId: deviceId,
      message: {
        type: 'show_health_ui',
        timestamp: Date.now()
      }
    });
  }
}

代码亮点

  • 手表数据采集:自动发现并连接手表设备,实时同步健康数据
  • PC大屏展示:将健康数据同步到PC端,利用大屏优势展示详细趋势
  • 全设备预警广播:健康异常时同时向所有设备推送预警
  • 设备角色分工:手表负责采集、手机负责分析、PC负责展示

六、健康状态与光效映射

在这里插入图片描述

6.1 健康状态机设计

// entry/src/main/ets/states/HealthStateMachine.ets

export class HealthStateMachine {
  private currentState: HealthState = HealthState.HEALTHY;
  private transitions: Map<HealthState, HealthState[]> = new Map([
    [HealthState.HEALTHY, [HealthState.ATTENTION, HealthState.EXERCISE]],
    [HealthState.ATTENTION, [HealthState.HEALTHY, HealthState.WARNING]],
    [HealthState.WARNING, [HealthState.ATTENTION, HealthState.DANGER, HealthState.RECOVERY]],
    [HealthState.DANGER, [HealthState.WARNING, HealthState.RECOVERY]],
    [HealthState.RECOVERY, [HealthState.HEALTHY, HealthState.ATTENTION]],
    [HealthState.EXERCISE, [HealthState.HEALTHY, HealthState.ATTENTION]]
  ]);

  async transition(newState: HealthState): Promise<boolean> {
    const validTransitions = this.transitions.get(this.currentState) || [];
    if (!validTransitions.includes(newState)) {
      console.warn(`Invalid transition: ${this.currentState} -> ${newState}`);
      return false;
    }

    // 执行状态退出逻辑
    await this.onExitState(this.currentState);

    // 更新状态
    this.currentState = newState;

    // 执行状态进入逻辑
    await this.onEnterState(newState);

    // 触发光效变化
    AppStorage.setOrCreate('health_state', newState);

    return true;
  }

  private async onEnterState(state: HealthState): Promise<void> {
    switch (state) {
      case HealthState.HEALTHY:
        // 播放健康提示音
        await this.playSound('healthy');
        break;
      case HealthState.ATTENTION:
        // 播放注意提示音
        await this.playSound('attention');
        break;
      case HealthState.WARNING:
        // 播放警告提示音
        await this.playSound('warning');
        break;
      case HealthState.DANGER:
        // 播放危险警报
        await this.playSound('danger');
        // 触发紧急联系人通知
        await this.notifyEmergency();
        break;
      case HealthState.RECOVERY:
        // 播放恢复提示音
        await this.playSound('recovery');
        break;
      case HealthState.EXERCISE:
        // 播放运动模式提示音
        await this.playSound('exercise');
        break;
    }
  }

  private async onExitState(state: HealthState): Promise<void> {
    console.info(`Exiting health state: ${state}`);
  }

  private async playSound(soundType: string): Promise<void> {
    console.info(`Playing health sound: ${soundType}`);
  }

  private async notifyEmergency(): Promise<void> {
    // 通知紧急联系人
    console.info('Notifying emergency contacts');
  }
}

七、关键技术总结

7.1 HMAF 2.0健康智能体开发清单

技术点 API/方法 应用场景
智能体会话创建 hmaf.createAgentSession({ mode: LLM, contextMemory: true }) 健康分析与建议
意图注册 intentEngine.registerIntents([...]) 健康意图识别
传感器采集 sensor.createSensor({ type: 'heart_rate' }) 实时数据采集
异常检测 detectAnomalies(data) 实时健康预警
趋势分析 analyzeTrends(history) 健康趋势预测
分布式同步 distributedService.createManager() 跨设备数据协同
语音预警 tts.createEngine({ voice: 'xiaoyi' }) 异常语音提醒

7.2 沉浸光感实现清单

技术点 API/方法 应用场景
健康光效映射 stateLightMap 6种健康状态对应6套光效
三层光效架构 Ambient + Glow + Animation 环境光+光晕+动画
5种动画类型 pulse/flow/rotate/flash/fade 不同健康状态
平滑过渡 animation({ duration: 800 }) 状态切换动画

7.3 悬浮导航适配要点

  1. 模块快速切换:底部悬浮页签支持心率/血氧/睡眠/运动四大模块快速切换
  2. 状态实时反馈:每个模块的页签颜色随其健康状态动态变化
  3. 悬停详情预览:PC端鼠标悬停展开模块详细信息(当前值/正常范围)
  4. 异常徽章提示:非健康状态时显示数字徽章,提醒用户关注

八、调试与性能优化

8.1 真机调试建议

  1. 传感器测试:在真机上测试心率、血氧等传感器的采集精度和稳定性
  2. 异常检测测试:验证不同阈值下的异常检测准确性
  3. 分布式测试:验证手表→手机→PC的数据同步链路稳定性

8.2 性能优化策略

  1. 数据采样优化:根据运动状态动态调整采样频率,静止时降低频率节省电量
  2. 本地缓存:缓存最近7天的健康数据,减少分布式同步次数
  3. 异常去重:相同异常类型在5分钟内只触发一次预警,避免重复打扰
  4. 分布式负载均衡:根据设备性能动态调整数据处理任务分配

九、总结与展望

本文基于HarmonyOS 6(API 23)的悬浮导航沉浸光感特性,完整实战了一款名为"健康守护灵"的AI健康监测智能体系统。核心创新点总结:

  1. 健康状态光效系统:6种健康状态(健康/注意/警告/危险/恢复/运动)实时映射为环境光色与动画效果,让用户"看见"自己的健康状态

  2. HMAF 2.0健康分析引擎:基于Intents Kit构建支持多源数据融合、实时异常预警和个性化建议的健康分析系统,支持三级优先级预警

  3. 主动异常预警:基于实时数据分析,主动触发预警光效和语音提醒,无需用户主动查看

  4. 悬浮健康导航:底部悬浮页签实现心率/血氧/睡眠/运动四大模块快速切换,支持PC端鼠标悬停预览

  5. 跨设备健康协同:利用HarmonyOS分布式软总线,实现"手表采集+手机分析+PC展示"的跨设备健康监测

未来扩展方向

  • 接入医疗级传感器:支持血压、血糖、心电图等医疗级数据采集
  • 探索AI医生:基于大语言模型的智能健康咨询,提供初步诊断建议
  • 结合保险服务:基于健康数据生成个性化保险方案
  • 家庭健康守护:支持家庭成员健康数据共享,实现家庭级健康监测

转载自:https://blog.csdn.net/u014727709/article/details/162390499
欢迎 👍点赞✍评论⭐收藏,欢迎指正

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐