Aggregating data in Health Connect can include basic aggregations or aggregating data into buckets. The following workflows show you how to do both.
Basic aggregations: cumulative
The following example shows you how to aggregate data for a data type.
suspend fun aggregateDistance(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response =
healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(DistanceRecord.DISTANCE_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
// The result may be null if no data is available in the time range.
val distanceTotalInMeters = response[DistanceRecord.DISTANCE_TOTAL]?.inMeters ?: 0L
}
Basic aggregations: statistical
Statistical aggregation will compute the minimum, maximum, or average values.
Here’s an example of statistical aggregation:
suspend fun aggregateHeartRate(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response =
healthConnectClient.aggregate(
AggregateRequest(
setOf(HeartRateRecord.BPM_MAX, HeartRateRecord.BPM_MIN),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
// The result may be null if no data is available in the time range.
val minimumHeartRate = response[HeartRateRecord.BPM_MIN]
val maximumHeartRate = response[HeartRateRecord.BPM_MAX]
}
Buckets
Health Connect allows you to aggregate into buckets. There are two types of buckets that can be used:
- Duration - where each bucket is of a fixed length in time, for example a minute or an hour.
- Period - where each bucket is of a conceptual length in time, for a example a week or a month.
Health Connect returns a list of buckets. Note that this list is sparse, so, where a bucket would contain no data, it is not present in the list.
The following shows an example of aggregating steps into monthly buckets:
suspend fun aggregateStepsIntoMonths(
healthConnectClient: HealthConnectClient,
startTime: LocalDateTime,
endTime: LocalDateTime
) {
val response =
healthConnectClient.aggregateGroupByPeriod(
AggregateGroupByPeriodRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
timeRangeSlicer = Period.ofMonths(1)
)
)
for (monthlyResult in response) {
// The result may be null if no data is available in the time range.
val totalSteps = monthlyResult.result[StepsRecord.COUNT_TOTAL]
}
}
To aggregate by Duration
, the approach follows the same pattern as previously, but instead uses the aggregateGroupByDuration(request: AggregateGroupByDurationRequest)
method.