如何通过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
相关产品推荐
相关产品推荐

