I want to get sleep and cycle tracking data from Google Fit to my app. I am aware that the API is no longer in use and we need to use the Health Connect app. I have retrieved most of the data, but I am having issues retrieving these two types of data from the Health Connect app.
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.")
}
}