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

如何通过Health Connect获取Google Fit睡眠及骑行踏频数据?

问题描述

需要将Google Fit中的睡眠及骑行追踪数据同步至自有应用,已知原Google Fit API已停用,需通过Health Connect实现数据获取。目前已成功获取多数类型数据,但睡眠数据和骑行踏频数据无法正常获取,相关代码实现如下:


HealthManager.kt

class HealthManager(context : Context) :  ViewModel(){

    val permissions = setOf(
        HealthPermission.getReadPermission(SleepSessionRecord::class),
        HealthPermission.getReadPermission(CyclingPedalingCadenceRecord::class),
    )

    suspend fun readSleepInputs(start: Instant, end: Instant): List<SleepSessionRecord> {
        return try {
            val request = ReadRecordsRequest(
                recordType = SleepSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(start, end)
            )
            val response = healthConnectClient.readRecords(request)
            response.records
        } catch (e: Exception) {
            Log.e("HealthConnect", "Error reading sleep records", e)
            emptyList()
        }
    }
    suspend fun readCyclePedalingCadence(start: Instant, end: Instant): List<CyclingPedalingCadenceRecord> {
        return try {
            val request = ReadRecordsRequest(
                recordType = CyclingPedalingCadenceRecord::class,
                timeRangeFilter = TimeRangeFilter.between(start, end)
            )
            val response = healthConnectClient.readRecords(request)
            response.records
        } catch (e: Exception) {
            emptyList()
        }
    }
}

DetailScreen.kt

@Composable
fun DetailScreen(healthManager: HealthManager, navController: NavHostController) {

    val sleepRecords by produceState<List<SleepSessionRecord>>(initialValue = emptyList()) {
        value = healthManager.readSleepInputs(
            start = java.time.Instant.now().minus(30, ChronoUnit.DAYS),
            end = java.time.Instant.now()
        )
    }

    val cyclingCadence by produceState<List<CyclingPedalingCadenceRecord>>(initialValue = emptyList()) {
        value = healthManager.readCyclePedalingCadence(
            start = java.time.Instant.now().minus(30, java.time.temporal.ChronoUnit.DAYS),
            end = java.time.Instant.now()
        )
    }
    
    if (sleepRecords.isNotEmpty()) {
        Text(text = "Sleep Records:", fontWeight = FontWeight.Bold, fontSize = 18.sp)
        sleepRecords.forEach { record ->
            Text(text = "Sleep Records: ${record.stages}")
        }
    } else {
        Text(text = "No sleep records available.")
    }

    Spacer(modifier = Modifier.height(24.dp))

    if (cyclingCadence.isNotEmpty()) {
        Text(
            text = "Cycling Cadence Records:",
            fontWeight = FontWeight.Bold,
            fontSize = 18.sp
        )
        cyclingCadence.forEach { record ->
            Text(text = "Cycling Cadence Records: ${record.samples.firstOrNull()?.revolutionsPerMinute} rpm")
        }
    } else {
        Text(text = "No cycling cadence records available.")
    }
    
}

排查与解决建议

1. 权限配置与申请

  • 确保AndroidManifest.xml中添加了对应权限:
    <uses-permission android:name="android.permission.health.READ_SLEEP" />
    <uses-permission android:name="android.permission.health.READ_CYCLING_PEDALING_CADENCE" />
    
  • 代码中仅声明权限不够,需在运行时通过HealthConnectClient.requestPermissions()主动申请,确认用户已授权。

2. 睡眠数据获取优化

  • 部分数据源会将睡眠阶段数据单独存储在SleepStageRecord中,而非SleepSessionRecord的stages字段,需同时读取该类型数据:
    suspend fun readSleepStages(start: Instant, end: Instant): List<SleepStageRecord> {
        return try {
            val request = ReadRecordsRequest(
                recordType = SleepStageRecord::class,
                timeRangeFilter = TimeRangeFilter.between(start, end)
            )
            healthConnectClient.readRecords(request).records
        } catch (e: Exception) {
            Log.e("HealthConnect", "Error reading sleep stages", e)
            emptyList()
        }
    }
    
  • 打开Health Connect应用确认Google Fit的睡眠数据已同步至其中。

3. 骑行踏频数据排查

  • 在readCyclePedalingCadence的catch块添加日志输出,定位具体错误:
    catch (e: Exception) {
        Log.e("HealthConnect", "Error reading cycling cadence", e)
        emptyList()
    }
    
  • 确认healthConnectClient已正确初始化:
    private val healthConnectClient by lazy {
        HealthConnectClient.getOrCreate(context)
    }
    
  • 踏频数据可能关联至CyclingSessionRecord,可尝试读取骑行会话数据,关联查询踏频信息。

4. 时间范围校验

  • 确认Instant时间范围匹配数据存储的时区(Instant为UTC时间,需确保与Google Fit同步到Health Connect的时间一致)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:54:51