设计概述

基于HarmonyOS 5的运动健康服务能力和HarmonyOS Design规范,我们将创建一个功能全面的运动检测应用,包含实时运动数据监测、运动类型识别、历史记录和健康分析等功能。

核心功能实现

1. 主界面设计 (ArkUI)

// MainPage.ets
@Entry
@Component
struct MainPage {
  @State currentTab: number = 0
  
  build() {
    Column() {
      // 运动数据概览
      if (this.currentTab === 0) {
        MotionOverview()
          .margin({ top: 16 })
      }
      
      // 内容区
      Tabs({ barPosition: BarPosition.End }) {
        TabContent() {
          MotionTrackingPage()
        }.tabBar('运动监测')
        
        TabContent() {
          HistoryPage()
        }.tabBar('历史记录')
        
        TabContent() {
          AnalysisPage()
        }.tabBar('健康分析')
      }
      .barWidth('100%')
      .barHeight(56)
      .onChange((index: number) => {
        this.currentTab = index
      })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

2. 运动监测页面

// MotionTrackingPage.ets
@Component
struct MotionTrackingPage {
  @State isTracking: boolean = false
  @State currentMotionType: string = '未开始'
  @State steps: number = 0
  @State distance: number = 0.0
  @State calories: number = 0
  @State heartRate: number = 0
  @State timer: number = 0
  
  private sensorManager: sensor.SensorManager = sensor.getSensorManager()
  private stepCounter: sensor.StepCounter | null = null
  
  aboutToAppear() {
    // 初始化传感器
    this.initSensors()
  }
  
  private initSensors() {
    // 获取步数计数器
    this.stepCounter = this.sensorManager.getDefaultSensor(sensor.SensorId.STEP_COUNTER)
    
    // 注册传感器回调
    this.sensorManager.on(sensor.SensorId.STEP_COUNTER, (data: sensor.SensorData) => {
      this.steps = data.steps
      this.calculateDerivedMetrics()
    })
  }
  
  private calculateDerivedMetrics() {
    // 计算距离和卡路里(简化计算)
    this.distance = this.steps * 0.7 // 假设步长0.7米
    this.calories = this.steps * 0.04 // 简化计算
  }
  
  build() {
    Column() {
      // 运动类型选择
      MotionTypeSelector({
        onTypeSelected: (type: string) => {
          this.currentMotionType = type
        }
      })
      .margin({ bottom: 20 })
      
      // 实时数据展示
      Grid() {
        GridItem() {
          MetricCard({
            value: this.timer.toString(),
            unit: '时间',
            icon: $r('app.media.ic_timer')
          })
        }
        
        GridItem() {
          MetricCard({
            value: this.steps.toString(),
            unit: '步数',
            icon: $r('app.media.ic_steps')
          })
        }
        
        GridItem() {
          MetricCard({
            value: this.distance.toFixed(2),
            unit: '公里',
            icon: $r('app.media.ic_distance')
          })
        }
        
        GridItem() {
          MetricCard({
            value: this.calories.toString(),
            unit: '卡路里',
            icon: $r('app.media.ic_calories')
          })
        }
      }
      .columnsTemplate('1fr 1fr')
      .rowsTemplate('1fr 1fr')
      .columnsGap(12)
      .rowsGap(12)
      .margin({ bottom: 20 })
      
      // 心率监测
      HeartRateMonitor({
        currentRate: this.heartRate,
        onRateChanged: (rate: number) => {
          this.heartRate = rate
        }
      })
      .margin({ bottom: 20 })
      
      // 控制按钮
      Button(this.isTracking ? '结束运动' : '开始运动')
        .width('80%')
        .height(48)
        .backgroundColor(this.isTracking ? '#FF5252' : '#4CAF50')
        .fontColor(Color.White)
        .onClick(() => {
          this.isTracking = !this.isTracking
          if (this.isTracking) {
            this.startTracking()
          } else {
            this.stopTracking()
          }
        })
    }
    .padding(16)
  }
  
  private startTracking() {
    // 开始计时器
    setInterval(() => {
      this.timer++
    }, 1000)
    
    // 启动传感器
    this.sensorManager.enableSensor(sensor.SensorId.STEP_COUNTER)
  }
  
  private stopTracking() {
    // 保存运动记录
    this.saveRecord()
    
    // 停止传感器
    this.sensorManager.disableSensor(sensor.SensorId.STEP_COUNTER)
  }
  
  private saveRecord() {
    const record = {
      type: this.currentMotionType,
      duration: this.timer,
      steps: this.steps,
      distance: this.distance,
      calories: this.calories,
      heartRate: this.heartRate,
      date: new Date().toISOString()
    }
    
    // 保存到数据库
    Database.saveRecord(record)
  }
}

3. 运动类型识别组件

// MotionTypeDetector.ets
@Component
export struct MotionTypeDetector {
  private motionDetector: motion.MotionDetector = motion.createMotionDetector()
  @State detectedType: string = '未知'
  
  aboutToAppear() {
    // 初始化运动检测
    this.motionDetector.on(motion.MotionType.WALKING, () => {
      this.detectedType = '步行'
    })
    
    this.motionDetector.on(motion.MotionType.RUNNING, () => {
      this.detectedType = '跑步'
    })
    
    this.motionDetector.on(motion.MotionType.CYCLING, () => {
      this.detectedType = '骑行'
    })
    
    this.motionDetector.start()
  }
  
  aboutToDisappear() {
    this.motionDetector.stop()
  }
  
  build() {
    Column() {
      Text('检测到: ' + this.detectedType)
        .fontSize(16)
      
      Image(this.getMotionIcon(this.detectedType))
        .width(40)
        .height(40)
        .margin({ top: 8 })
    }
  }
  
  private getMotionIcon(type: string): Resource {
    switch(type) {
      case '步行': return $r('app.media.ic_walking')
      case '跑步': return $r('app.media.ic_running')
      case '骑行': return $r('app.media.ic_cycling')
      default: return $r('app.media.ic_unknown_motion')
    }
  }
}

4. 历史记录页面

// HistoryPage.ets
@Component
struct HistoryPage {
  @State records: Array<MotionRecord> = []
  
  aboutToAppear() {
    this.loadRecords()
  }
  
  private loadRecords() {
    Database.getRecords().then((data) => {
      this.records = data
    })
  }
  
  build() {
    List() {
      ForEach(this.records, (record) => {
        ListItem() {
          MotionRecordCard({ record: record })
        }
        .onClick(() => {
          router.push({
            url: 'pages/RecordDetailPage',
            params: { recordId: record.id }
          })
        })
      })
    }
    .divider({ strokeWidth: 1, color: '#EEEEEE' })
    .edgeEffect(EdgeEffect.Spring)
  }
}

5. 健康分析图表

// AnalysisChart.ets
@Component
export struct AnalysisChart {
  @State data: Array<{ date: string, value: number }> = []
  
  build() {
    Column() {
      // 周运动数据图表
      Text('本周运动趋势')
        .fontSize(18)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 16 })
      
      Chart({
        datasets: [
          {
            data: this.data,
            strokeWidth: 2,
            gradient: {
              colors: ['#6200EE', '#03DAC6'],
              direction: GradientDirection.TOP_BOTTOM
            }
          }
        ],
        xAxis: {
          axisTick: 5,
          axisLabel: (value: string) => {
            return value.substring(5) // 显示简写日期
          }
        },
        yAxis: {
          min: 0,
          max: Math.max(...this.data.map(item => item.value)) * 1.2,
          axisTick: 5
        }
      })
      .width('100%')
      .height(200)
      .margin({ bottom: 24 })
      
      // 运动类型分布
      Text('运动类型分布')
        .fontSize(18)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 16 })
      
      PieChart({
        data: [
          { value: 45, name: '步行', color: '#4CAF50' },
          { value: 30, name: '跑步', color: '#2196F3' },
          { value: 25, name: '骑行', color: '#FF9800' }
        ],
        showPercentage: true
      })
      .width(200)
      .height(200)
    }
    .padding(16)
  }
}

设计要点

  1. ​传感器集成​​:

    // 传感器管理封装
    class SensorService {
      private static instance: SensorService
      private sensorManager: sensor.SensorManager
      
      private constructor() {
        this.sensorManager = sensor.getSensorManager()
      }
      
      public static getInstance(): SensorService {
        if (!SensorService.instance) {
          SensorService.instance = new SensorService()
        }
        return SensorService.instance
      }
      
      public startStepCounter(callback: (steps: number) => void) {
        const stepCounter = this.sensorManager.getDefaultSensor(sensor.SensorId.STEP_COUNTER)
        this.sensorManager.on(sensor.SensorId.STEP_COUNTER, (data: sensor.SensorData) => {
          callback(data.steps)
        })
        this.sensorManager.enableSensor(sensor.SensorId.STEP_COUNTER)
      }
    }
  2. ​数据持久化​​:

    // 数据库操作封装
    import relationalStore from '@ohos.data.relationalStore'
    
    class Database {
      private static STORE_CONFIG = {
        name: 'MotionTracker.db',
        securityLevel: relationalStore.SecurityLevel.S1
      }
      
      private static TABLE_SCHEMA = {
        tableName: 'records',
        columns: [
          { fieldName: 'id', type: relationalStore.ValueType.INTEGER, isPrimaryKey: true },
          { fieldName: 'type', type: relationalStore.ValueType.STRING },
          { fieldName: 'duration', type: relationalStore.ValueType.INTEGER },
          // 其他字段...
        ]
      }
      
      static async saveRecord(record: MotionRecord) {
        const rdbStore = await relationalStore.getRdbStore(this.STORE_CONFIG)
        await rdbStore.insert(this.TABLE_SCHEMA.tableName, record)
      }
    }
  3. ​性能优化​​:

    // 使用Worker处理传感器数据
    const worker = new Worker('workers/SensorWorker.ts')
    
    worker.onmessage = (message) => {
      // 处理传感器数据
    }
    
    // 在Worker中
    const sensorManager = sensor.getSensorManager()
    sensorManager.on(sensor.SensorId.STEP_COUNTER, (data) => {
      workerPort.postMessage(data)
    })
  4. ​权限管理​​:

    // 检查并请求必要权限
    import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
    
    async function checkPermissions() {
      const atManager = abilityAccessCtrl.createAtManager()
      try {
        const permissions = [
          'ohos.permission.HEALTH_DATA',
          'ohos.permission.ACTIVITY_MOTION'
        ]
        
        const result = await atManager.requestPermissionsFromUser(permissions)
        return result.granted.every(granted => granted)
      } catch (err) {
        console.error('权限请求失败:', err)
        return false
      }
    }

总结

通过HarmonyOS 5的运动健康服务能力和ArkUI框架,我们实现了一个功能全面的运动检测应用,具有以下特点:

  1. ​多维度运动监测​​:实时跟踪步数、距离、卡路里、心率等数据
  2. ​智能运动识别​​:自动识别步行、跑步、骑行等运动类型
  3. ​数据可视化​​:通过图表展示运动趋势和健康分析
  4. ​历史记录​​:完整记录每次运动数据,支持详情查看
  5. ​权限与安全​​:完善的权限管理和数据保护机制

该应用充分利用了HarmonyOS的传感器能力、分布式技术和UI框架,为用户提供了专业级的运动监测体验,同时符合HarmonyOS Design的设计规范,确保良好的用户体验。

Logo

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

更多推荐