You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Google Fit API将WearOS设备心率数据同步至安卓手机

我之前做过类似的WearOS与手机通过Google Fit同步心率数据的项目,结合你的华为Watch 2 + 三星S7的场景,整理了一套可行的落地方案,你可以跟着一步步来验证:

一、先确认前提条件

这些是后续实现的基础,务必先排查:

  • 确保华为Watch 2的WearOS系统是最新版本,且已经和三星S7完成蓝牙配对、WearOS官方应用绑定
  • 手机和手表端都登录了同一个Google账号,且Google Fit服务在两端都正常启用(可以打开Google Fit App确认状态)
  • 你的手机应用和手表应用都已经在Google Cloud Console配置好Google Fit API权限,包括对应两端包名和签名的OAuth 2.0客户端ID

二、核心实现步骤

1. 手表端:获取心率数据并写入Google Fit

WearOS上可以直接通过Google Fit的传感器API读取心率,再将数据写入Fit的数据源中,这样手机端就能同步获取到。

Kotlin代码示例:

// 初始化Google Fit客户端,申请写入心率数据的权限
private val fitnessOptions = FitnessOptions.builder()
    .addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_WRITE)
    .build()

private fun initHeartRateListener(context: Context, activity: Activity) {
    val account = GoogleSignIn.getAccountForExtension(context, fitnessOptions)
    
    // 检查权限,无权限则发起请求
    if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {
        GoogleSignIn.requestPermissions(
            activity,
            REQUEST_OAUTH_PERMISSIONS,
            account,
            fitnessOptions
        )
    } else {
        startHeartRateMonitoring(context, account)
    }
}

private fun startHeartRateMonitoring(context: Context, account: GoogleSignInAccount) {
    // 监听实时心率数据
    Fitness.getSensorsClient(context, account)
        .add(
            SensorRequest.Builder()
                .setDataType(DataType.TYPE_HEART_RATE_BPM)
                .setSamplingRate(1, TimeUnit.SECONDS) // 每秒采样一次
                .build(),
            object : OnDataPointListener {
                override fun onDataPoint(dataPoint: DataPoint) {
                    for (field in dataPoint.dataType.fields) {
                        val heartRate = dataPoint.getValue(field).asFloat()
                        // 将读取到的心率写入Google Fit
                        insertHeartRateToFit(context, account, heartRate, dataPoint.timestamp)
                    }
                }
            }
        )
}

// 插入心率数据到Google Fit数据源
private fun insertHeartRateToFit(context: Context, account: GoogleSignInAccount, heartRate: Float, timestamp: Long) {
    val dataSource = DataSource.Builder()
        .setAppPackageName(context.packageName)
        .setDataType(DataType.TYPE_HEART_RATE_BPM)
        .setType(DataSource.TYPE_RAW)
        .setStreamName("HuaweiWatch2_HeartRate_Stream") // 自定义唯一流名称,避免冲突
        .build()

    val dataPoint = DataPoint.builder(dataSource)
        .setTimestamp(timestamp, TimeUnit.MILLISECONDS)
        .setField(Field.FIELD_BPM, heartRate)
        .build()

    Fitness.getHistoryClient(context, account)
        .insertData(DataSet.builder(dataSource).add(dataPoint).build())
        .addOnSuccessListener { /* 数据写入成功,可添加日志或回调 */ }
        .addOnFailureListener { e -> /* 处理写入失败,比如打印Logcat */ }
}

// 定义权限请求码
private const val REQUEST_OAUTH_PERMISSIONS = 1001

2. 手机端:从Google Fit读取同步的心率数据

手机端需要配置读取心率数据的权限,然后通过Google Fit API监听或读取手表端写入的数据。

Kotlin代码示例:

// 初始化Google Fit客户端,申请读取心率数据的权限
private val fitnessOptions = FitnessOptions.builder()
    .addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
    .build()

private fun initFitDataReader(context: Context, activity: Activity) {
    val account = GoogleSignIn.getAccountForExtension(context, fitnessOptions)
    
    if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {
        GoogleSignIn.requestPermissions(
            activity,
            REQUEST_OAUTH_PERMISSIONS,
            account,
            fitnessOptions
        )
    } else {
        startRealTimeHeartRateListener(context, account)
    }
}

// 实时监听心率数据更新
private fun startRealTimeHeartRateListener(context: Context, account: GoogleSignInAccount) {
    Fitness.getSensorsClient(context, account)
        .add(
            SensorRequest.Builder()
                .setDataType(DataType.TYPE_HEART_RATE_BPM)
                .setSamplingRate(1, TimeUnit.SECONDS)
                .build(),
            object : OnDataPointListener {
                override fun onDataPoint(dataPoint: DataPoint) {
                    for (field in dataPoint.dataType.fields) {
                        val heartRate = dataPoint.getValue(field).asFloat()
                        // 在这里处理心率数据,比如更新App UI、存储到本地等
                        updateHeartRateUI(heartRate)
                    }
                }
            }
        )
}

// 可选:读取历史心率数据(比如最近5分钟)
private fun readHistoryHeartRate(context: Context, account: GoogleSignInAccount) {
    val readRequest = DataReadRequest.Builder()
        .read(DataType.TYPE_HEART_RATE_BPM)
        .setTimeRange(System.currentTimeMillis() - 300000, System.currentTimeMillis(), TimeUnit.MILLISECONDS)
        .build()

    Fitness.getHistoryClient(context, account)
        .readData(readRequest)
        .addOnSuccessListener { response ->
            for (dataSet in response.dataSets) {
                processHeartRateDataSet(dataSet)
            }
        }
}

private fun processHeartRateDataSet(dataSet: DataSet) {
    for (dataPoint in dataSet.dataPoints) {
        for (field in dataPoint.dataType.fields) {
            val heartRate = dataPoint.getValue(field).asFloat()
            // 处理历史数据
        }
    }
}

private const val REQUEST_OAUTH_PERMISSIONS = 1002

三、关键注意事项

  • 权限配置要精准:手机和手表的OAuth客户端ID必须分别配置,包名和签名指纹要和Google Cloud Console中的记录完全一致(包括debug和release签名),否则会出现权限拒绝的问题
  • 数据源唯一性:手表端设置的setStreamName要保证唯一,避免和其他应用的数据源冲突,导致数据读取混乱
  • 后台运行稳定性:在三星S7的电池优化设置中,把你的目标应用和WearOS官方应用设置为“不优化”,防止系统杀死后台同步进程
  • 实时性优化:如果需要高实时性,优先使用传感器监听(getSensorsClient)而不是历史数据读取,这样能最快获取到手表端的心率数据

四、排查问题的小技巧

如果之前的代码没生效,可以按以下步骤排查:

  1. 检查两端Google账号是否一致,Google Fit App是否能正常显示心率数据
  2. 查看Logcat中的错误日志,重点关注权限、API调用失败、数据源不存在等关键词
  3. 在手表端的心率回调中打印日志,确认是否真的读取到了有效的心率值
  4. 验证Google Cloud Console中的Google Fit API是否已启用,客户端ID的签名指纹是否正确

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

火山引擎 最新活动