You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Wear OS上保存传输智能手表传感器数据并导出为CSV

实现优化与问题解决方案

现有实现的已知问题

你当前的代码有几个直接影响写入可靠性的问题:

  • 直接使用相对路径data.csv,Wear OS基于Android系统,相对路径默认指向应用私有目录的根路径,后续你查找文件时会无法定位路径
  • 缺少数据分隔符与时间戳:所有PPG数值会连续写入无换行,最终得到的CSV文件无法正确拆分;同时PPG数据必须匹配采样时间戳才能用于后续信号分析,仅存数值没有实用价值
  • 未做缓冲区刷新与资源释放:FileWriter默认带缓冲区,你仅调用write()方法不会立即落盘,应用退后台、崩溃时会丢失大量数据;且onResume中初始化的writer没有在onPause等生命周期回调中关闭,会出现资源泄漏
  • 主线程执行IO操作:onSensorChanged运行在主线程,PPG采样频率通常在25~100Hz,频繁IO操作会阻塞主线程导致界面卡顿甚至应用崩溃

存储位置选择

优先选择手表本地应用私有目录存储:

  • 不需要额外申请存储权限,写入速度快,不会因为蓝牙连接不稳定丢失数据
  • 如果需要实时同步到手机,可采用Wear OS提供的Wearable Data Layer API批量同步数据,避免高频传输带来的功耗损耗

写入逻辑优化方案

1. 基础逻辑调整

  • 写入路径显式指定为应用私有目录:new FileWriter(new File(getFilesDir(), "data.csv"), true)
  • 每行数据增加时间戳与换行符:写入格式改为System.currentTimeMillis() + "," + sensorData + "\n"
  • 生命周期匹配:在onPause回调中添加writer.flush() + writer.close()逻辑,确保退出时所有缓冲区数据落盘
  • 异步写入:用ConcurrentLinkedQueue缓存传感器数据,启动单独的后台线程批量写入文件,避免阻塞主线程

2. 优化后代码示例

首先在MainActivity中新增成员变量:

private ConcurrentLinkedQueue<String> dataQueue = new ConcurrentLinkedQueue<>();
private ExecutorService writeExecutor = Executors.newSingleThreadExecutor();
private volatile boolean isWriting = true;
private FileWriter writer;

修改onResume初始化逻辑:

@Override
protected void onResume() {
    super.onResume();
    isWriting = true;
    try {
        // 显式指定存储路径
        File csvFile = new File(getFilesDir(), "data.csv");
        writer = new FileWriter(csvFile, true);
        // 启动后台写入线程
        writeExecutor.execute(() -> {
            while (isWriting) {
                String data = dataQueue.poll();
                if (data != null) {
                    try {
                        writer.write(data);
                        // 每满10条刷一次缓冲区,可根据采样频率调整
                        if (dataQueue.size() % 10 == 0) {
                            writer.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    // 队列为空时休眠10ms降低CPU占用
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
            // 退出循环后刷入剩余数据并关闭写入器
            try {
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}

修改onSensorChanged逻辑,仅把数据推入队列:

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == 65572) {
        float sensorData = event.values[0];
        String dataString = System.currentTimeMillis() + "," + sensorData + "\n";
        textView.setText(Float.toString(sensorData));
        dataQueue.offer(dataString);
    }
}

添加onPause销毁逻辑:

@Override
protected void onPause() {
    super.onPause();
    isWriting = false;
    writeExecutor.shutdown();
}

CSV文件导出到PC的方法

方法1:ADB直接拉取(开发调试阶段最方便)

  1. 手表开启开发者选项与USB调试,通过USB连接电脑,或者使用无线ADB连接
  2. 执行命令直接拉取文件:
adb pull /data/data/[你的应用包名]/files/data.csv ./local_data.csv

拉取到本地的CSV文件可直接导入MATLAB做信号分析。

方法2:用户端可视化导出

在应用内添加导出按钮,点击后触发:

  1. 将CSV文件通过Wearable Data Layer同步到配对的手机端应用
  2. 手机端应用调用系统分享能力,支持用户将文件发送到邮箱、保存到公共存储或者传输到PC

内容的提问来源于stack exchange,提问作者casella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:54:01