在这里插入图片描述

前言

在现代运动健康应用中,心率监测是最核心的功能之一。通过实时监测用户的心率数据,应用可以帮助用户了解自己的运动强度,避免过度运动带来的健康风险。本文将详细介绍如何在Flutter与OpenHarmony平台上实现一个专业的心率监测组件,包括数据采集、实时显示、历史记录等功能模块的完整实现方案。

心率监测组件的设计需要考虑多个方面:首先是数据的准确性,需要与硬件传感器进行良好的交互;其次是用户体验,需要以直观的方式展示心率数据;最后是性能优化,确保实时数据更新不会影响应用的流畅度。

Flutter端心率数据模型定义

class HeartRateData {
  final int bpm;
  final DateTime timestamp;
  final String zone;
  
  HeartRateData({
    required this.bpm,
    required this.timestamp,
    required this.zone,
  });
}

在Flutter端,我们首先需要定义心率数据的模型类。这个模型包含三个核心属性:bpm表示每分钟心跳次数,这是心率的标准计量单位;timestamp记录数据采集的时间戳,用于后续的历史数据分析和图表展示;zone表示当前心率所处的运动区间,如静息区、燃脂区、有氧区、无氧区等。通过这种结构化的数据模型,我们可以方便地进行数据传输、存储和展示。

心率区间计算工具类

class HeartRateZoneCalculator {
  static String calculateZone(int bpm, int age) {
    int maxHR = 220 - age;
    double percentage = bpm / maxHR;
    
    if (percentage < 0.5) return '静息区';
    if (percentage < 0.6) return '热身区';
    if (percentage < 0.7) return '燃脂区';
    if (percentage < 0.8) return '有氧区';
    if (percentage < 0.9) return '无氧区';
    return '极限区';
  }
}

心率区间的计算是运动应用中非常重要的功能。我们采用经典的最大心率公式(220减去年龄)来计算用户的理论最大心率,然后根据当前心率占最大心率的百分比来判断所处的运动区间。不同的运动区间对应不同的训练效果:静息区适合恢复休息,热身区用于运动前的准备活动,燃脂区是减脂的最佳区间,有氧区可以提升心肺功能,无氧区用于提升运动能力,极限区则需要谨慎进入。这种分区方式帮助用户科学地控制运动强度。

OpenHarmony端心率传感器订阅

import sensor from '@ohos.sensor';

let heartRateSensorId: number = -1;

function subscribeHeartRate(): void {
  sensor.on(sensor.SensorId.HEART_RATE, (data) => {
    let heartRate = data.heartRate;
    console.info('当前心率: ' + heartRate);
  });
}

在OpenHarmony平台上,我们通过系统提供的sensor模块来订阅心率传感器数据。sensor.on方法允许我们注册一个回调函数,当传感器检测到新的心率数据时,系统会自动调用这个回调函数并传入最新的数据。这种事件驱动的方式非常适合处理实时传感器数据,可以确保我们及时获取到最新的心率信息。需要注意的是,在实际应用中,我们还需要处理传感器不可用的情况,并提供相应的用户提示。

Flutter心率显示组件

class HeartRateDisplay extends StatelessWidget {
  final int currentBpm;
  final String zone;
  
  const HeartRateDisplay({
    Key? key,
    required this.currentBpm,
    required this.zone,
  }) : super(key: key);
  
  
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(20),
      decoration: BoxDecoration(
        gradient: _getZoneGradient(zone),
        borderRadius: BorderRadius.circular(16),
      ),
      child: Column(
        children: [
          Icon(Icons.favorite, color: Colors.white, size: 48),
          Text('$currentBpm', style: TextStyle(fontSize: 64, color: Colors.white)),
          Text('BPM', style: TextStyle(fontSize: 18, color: Colors.white70)),
          Text(zone, style: TextStyle(fontSize: 16, color: Colors.white)),
        ],
      ),
    );
  }
}

心率显示组件是用户界面中最直观的部分。我们使用StatelessWidget来构建这个组件,因为它只负责展示数据,不需要管理内部状态。组件的设计采用了渐变背景,不同的心率区间会显示不同的颜色渐变,让用户一眼就能识别当前的运动强度。中央大字体显示当前心率数值,配合心形图标和BPM单位标识,整体视觉效果清晰明了。底部显示当前所处的心率区间名称,帮助用户理解数据的含义。

OpenHarmony心率数据持久化

import dataPreferences from '@ohos.data.preferences';

async function saveHeartRateRecord(bpm: number, timestamp: number): Promise<void> {
  let preferences = await dataPreferences.getPreferences(globalThis.context, 'heartrate_store');
  let records = await preferences.get('records', '[]');
  let recordArray = JSON.parse(records as string);
  
  recordArray.push({ bpm: bpm, timestamp: timestamp });
  await preferences.put('records', JSON.stringify(recordArray));
  await preferences.flush();
}

数据持久化是运动应用的重要功能,用户需要查看历史运动数据来跟踪自己的健康状况。在OpenHarmony中,我们使用dataPreferences模块来实现轻量级的数据存储。这个方法首先获取名为heartrate_store的偏好设置实例,然后读取已有的记录数组,将新的心率数据追加到数组中,最后保存并刷新到磁盘。这种方式适合存储结构简单、数据量不大的场景。对于更复杂的数据存储需求,可以考虑使用关系型数据库。

Flutter心率趋势图表组件

class HeartRateTrendChart extends StatelessWidget {
  final List<HeartRateData> dataPoints;
  
  const HeartRateTrendChart({Key? key, required this.dataPoints}) : super(key: key);
  
  
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(double.infinity, 200),
      painter: HeartRateChartPainter(dataPoints: dataPoints),
    );
  }
}

趋势图表是展示心率变化的最佳方式。我们使用CustomPaint组件来绑定自定义的绑定器,这样可以完全控制图表的绘制逻辑。dataPoints参数接收一个心率数据列表,包含了一段时间内的所有心率记录。通过将这些数据点连接成曲线,用户可以直观地看到心率的变化趋势,识别运动过程中的峰值和低谷,从而更好地了解自己的运动表现。

心率图表绑定器实现

class HeartRateChartPainter extends CustomPainter {
  final List<HeartRateData> dataPoints;
  
  HeartRateChartPainter({required this.dataPoints});
  
  
  void paint(Canvas canvas, Size size) {
    if (dataPoints.isEmpty) return;
    
    Paint linePaint = Paint()
      ..color = Colors.red
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;
    
    Path path = Path();
    double xStep = size.width / (dataPoints.length - 1);
    
    for (int i = 0; i < dataPoints.length; i++) {
      double x = i * xStep;
      double y = size.height - (dataPoints[i].bpm - 40) / 160 * size.height;
      if (i == 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    canvas.drawPath(path, linePaint);
  }
  
  
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

自定义绑定器是Flutter中实现复杂图形的核心技术。在paint方法中,我们首先检查数据是否为空,然后创建画笔对象设置线条颜色和宽度。绑制逻辑是将心率数据映射到画布坐标系上:x轴表示时间,均匀分布所有数据点;y轴表示心率值,我们假设心率范围在40-200之间进行归一化处理。通过Path对象连接所有数据点,最后调用drawPath方法绘制曲线。shouldRepaint返回true确保数据更新时图表会重新绘制。

OpenHarmony心率告警服务

import notification from '@ohos.notificationManager';

async function sendHeartRateAlert(bpm: number): Promise<void> {
  let notificationRequest: notification.NotificationRequest = {
    id: 1,
    content: {
      notificationContentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
      normal: {
        title: '心率告警',
        text: `当前心率${bpm}BPM,请注意休息`,
      }
    }
  };
  await notification.publish(notificationRequest);
}

心率告警是保护用户健康的重要功能。当检测到心率异常(过高或过低)时,应用需要及时提醒用户。在OpenHarmony中,我们使用notificationManager模块来发送系统通知。通知请求对象包含唯一标识id和内容对象,内容类型设置为基础文本通知,包含标题和正文。通过publish方法发送通知后,用户即使不在应用界面也能收到提醒,这对于运动安全非常重要。

Flutter心率状态管理

class HeartRateProvider extends ChangeNotifier {
  int _currentBpm = 0;
  List<HeartRateData> _history = [];
  bool _isMonitoring = false;
  
  int get currentBpm => _currentBpm;
  List<HeartRateData> get history => _history;
  bool get isMonitoring => _isMonitoring;
  
  void updateHeartRate(int bpm) {
    _currentBpm = bpm;
    _history.add(HeartRateData(
      bpm: bpm,
      timestamp: DateTime.now(),
      zone: HeartRateZoneCalculator.calculateZone(bpm, 25),
    ));
    notifyListeners();
  }
  
  void toggleMonitoring() {
    _isMonitoring = !_isMonitoring;
    notifyListeners();
  }
}

状态管理是Flutter应用架构的核心。我们使用Provider模式,通过继承ChangeNotifier来创建心率状态管理类。这个类维护三个状态:当前心率值、历史记录列表和监测开关状态。通过getter方法暴露状态,通过业务方法修改状态并调用notifyListeners通知所有监听者更新UI。这种模式实现了数据与视图的分离,使代码更易于维护和测试。当心率数据更新时,所有依赖这个Provider的组件都会自动重建。

总结

本文详细介绍了Flutter与OpenHarmony平台上心率监测组件的完整实现方案。从数据模型定义到传感器订阅,从UI展示到数据持久化,从图表绑制到告警通知,涵盖了心率监测功能的各个方面。通过合理的架构设计和代码组织,我们可以构建出一个功能完善、用户体验良好的心率监测模块,为运动健康应用提供坚实的技术基础。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐