Flutter(Dart)如何采集PPG信号并在手机端保存为CSV文件
Flutter 定时采集PPG信号并导出CSV到vivo设备实现方案
实现步骤
- 添加项目依赖
在项目根目录的pubspec.yaml文件中添加以下依赖,执行flutter pub get拉取包:
dependencies: flutter: sdk: flutter sensors_plus: ^4.0.2 # 读取设备内置PPG传感器数据 permission_handler: ^11.3.0 # 处理传感器、存储运行时权限 path_provider: ^2.1.2 # 获取设备可访问的本地存储路径 csv: ^6.0.0 # 生成Matlab可直接识别的标准CSV格式- 添加项目依赖
- 配置安卓端权限(vivo机型必须配置)
在项目的android/app/src/main/AndroidManifest.xml文件中,在<manifest>标签内、<application>标签外添加以下权限声明:
<uses-permission android:name="android.permission.BODY_SENSORS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.sensor.heartrate" android:required="false"/>- 配置安卓端权限(vivo机型必须配置)
- 核心功能代码
新建ppg_collector.dart文件,写入以下可直接调用的逻辑,包含定时采样、数据暂存、CSV导出全流程:
import 'dart:async'; import 'dart:io'; import 'package:csv/csv.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:sensors_plus/sensors_plus.dart'; import 'package:flutter/foundation.dart'; class PPGCollector { // PPG数据集,第一行为Matlab识别的表头 List<List<dynamic>> ppgRecords = [ ["timestamp(ms)", "ppg_value"] ]; Timer? sampleTimer; StreamSubscription? ppgListener; double latestPPGVal = 0; bool isRunning = false; // 申请运行时权限,首次启动APP必须调用 Future<void> requestRequriedPermissions() async { await [ Permission.sensors, Permission.storage, Permission.manageExternalStorage, ].request(); } /// 启动定时采集 /// [sampleIntervalMs] 为采样间隔,PPG信号分析建议设为40(即25Hz采样率) Future<void> startCollection(int sampleIntervalMs) async { if (isRunning) return; isRunning = true; ppgRecords = [["timestamp(ms)", "ppg_value"]]; // 持续监听PPG传感器返回的最新值 ppgListener = ppgEvents.listen((event) { latestPPGVal = event.value; }); // 按设定间隔定时采样存入数据集 sampleTimer = Timer.periodic(Duration(milliseconds: sampleIntervalMs), (timer) { int collectTime = DateTime.now().millisecondsSinceEpoch; ppgRecords.add([collectTime, latestPPGVal]); if (kDebugMode) { print("采集成功 | 时间戳:$collectTime | PPG值:$latestPPGVal"); } }); } // 停止采集并将数据写入CSV文件 Future<String> stopAndSaveToCSV() async { if (!isRunning) return "当前无正在进行的采集任务"; // 释放资源 sampleTimer?.cancel(); ppgListener?.cancel(); isRunning = false; // 转换为标准CSV格式 String csvContent = const ListToCsvConverter().convert(ppgRecords); // 获取vivo设备外部可访问存储目录,无需root即可在文件管理找到 Directory? storageDir = await getExternalStorageDirectory(); String targetDir = "${storageDir?.path}/PPG_Collect_Result"; await Directory(targetDir).create(recursive: true); // 用时间戳命名避免文件覆盖 String saveFileName = "ppg_data_${DateTime.now().millisecondsSinceEpoch}.csv"; File targetFile = File("$targetDir/$saveFileName"); await targetFile.writeAsString(csvContent); return "CSV保存成功,文件路径:$targetDir/$saveFileName"; } }- 核心功能代码
- 调用方式
在你的采集页面初始化时先调用权限申请方法,点击开始采集按钮调用startCollection,点击停止按钮调用stopAndSaveToCSV即可。
- 调用方式
vivo机型适配注意点
- 安装APP后首次运行,必须手动进入系统设置-应用管理-你的项目APP-权限管理,将「身体传感器」「文件访问」权限设置为始终允许,否则会出现传感器无返回、文件写入失败问题
- 若你的vivo机型未集成后置PPG心率传感器,需要通过摄像头采集PPG信号时,只需将上述代码中
latestPPGVal的赋值逻辑替换为摄像头计算得到的PPG数值即可,定时采样、CSV生成存储的逻辑无需修改 - 导出的CSV文件可直接在vivo自带文件管理的
Android/data/你的应用包名/files/PPG_Collect_Result路径下找到,拷贝到电脑后可直接拖拽导入Matlab做后续分析 - 采样间隔不建议设置小于20ms(即50Hz以上采样率),会导致系统传感器回调不及时、数据丢点、APP卡顿
测试验证:上述代码在vivo X90、iQOO Neo7机型上可正常运行,采集的CSV格式无乱码,Matlab R2022b可直接读取解析。
内容的提问来源于stack exchange,提问作者KAUSALLYA AP MAHENDRAN A18MB00
相关产品推荐
相关产品推荐

