在 Health Connect 中聚合数据包括基本聚合或将数据聚合到存储分区中。以下工作流程展示了如何执行这两种操作。
基本聚合
要对数据使用基本聚合,请在您的 HealthConnectClient
对象上使用 aggregate
函数。它接受一个 AggregateRequest
对象,您可以在其中添加度量类型和时间范围作为其参数。基本聚合的调用方式取决于所使用的度量类型。
累积聚合
累积聚合计算总值。
以下示例展示了如何聚合某种数据类型的数据
suspend fun aggregateDistance(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
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
} catch (e: Exception) {
// Run error handling here
}
}
统计聚合
统计聚合计算包含样本的记录的最小值、最大值或平均值。
以下示例展示了如何使用统计聚合
suspend fun aggregateHeartRate(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
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]
} catch (e: Exception) {
// Run error handling here
}
}
存储分区
Health Connect 还可以让您将数据聚合到存储分区中。您可以使用的两种存储分区类型包括持续时间和周期。
调用后,它们会返回一个存储分区列表。请注意,该列表可能是稀疏的,因此如果存储分区不包含任何数据,则不会将其包含在列表中。
持续时间
在这种情况下,聚合数据会按固定时间长度(例如一分钟或一小时)分成存储分区。要将数据聚合到存储分区中,请使用 aggregateGroupByDuration
。它接受一个 AggregateGroupByDurationRequest
对象,您可以在其中添加度量类型、时间范围和 Duration
作为参数。
以下显示了将步数聚合为分钟级存储分区的示例
suspend fun aggregateStepsIntoMinutes(
healthConnectClient: HealthConnectClient,
startTime: LocalDateTime,
endTime: LocalDateTime
) {
try {
val response =
healthConnectClient.aggregateGroupByDuration(
AggregateGroupByDurationRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
timeRangeSlicer = Duration.ofMinutes(1L)
)
)
for (durationResult in response) {
// The result may be null if no data is available in the time range
val totalSteps = durationResult.result[StepsRecord.COUNT_TOTAL]
}
} catch (e: Exception) {
// Run error handling here
}
}
周期
在这种情况下,聚合数据会按基于日期的时长(例如一周或一个月)分成存储分区。要将数据聚合到存储分区中,请使用 aggregateGroupByPeriod
。它接受一个 AggregateGroupByPeriodRequest
对象,您可以在其中添加度量类型、时间范围和 Period
作为参数。
以下显示了将步数聚合为月度存储分区的示例
suspend fun aggregateStepsIntoMonths(
healthConnectClient: HealthConnectClient,
startTime: LocalDateTime,
endTime: LocalDateTime
) {
try {
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]
}
} catch (e: Exception) {
// Run error handling here
}
}
读取限制
默认情况下,所有应用都可以读取 Health Connect 中自首次授予权限之日起最多 30 天前的数据。
如果您需要将读取权限扩展到任何默认限制之外,请请求 PERMISSION_READ_HEALTH_DATA_HISTORY
权限。否则,如果没有此权限,尝试读取超过 30 天的记录将导致错误。
已删除应用的权限历史记录
如果用户删除您的应用,包括历史记录权限在内的所有权限都将被撤销。如果用户重新安装您的应用并再次授予权限,则相同的默认限制将适用,您的应用可以读取 Health Connect 中自新日期起最多 30 天前的数据。
例如,假设用户在 2023 年 5 月 10 日删除您的应用,然后在 2023 年 5 月 15 日重新安装应用并授予读取权限。您的应用现在默认可以读取数据的最早日期是 2023 年 4 月 15 日。
受用户选择的应用优先级影响的聚合数据
最终用户可以设置已与 Health Connect 集成的睡眠和活动应用的优先级。只有最终用户才能修改这些优先级列表。当您执行聚合读取时,聚合 API 会考虑任何重复数据,并仅保留优先级最高的应用的数据。如果用户有多个应用同时写入相同类型的数据(例如步数或距离),则可能存在重复数据。
有关最终用户如何设置应用优先级的信息,请参阅管理 Health Connect 数据。
用户可以添加或删除应用,以及更改其优先级。用户可能希望删除正在写入重复数据的应用,以便 Health Connect 屏幕上的数据总计与他们赋予最高优先级的应用的数据总计相同。数据总计是实时更新的。
即使聚合 API 根据用户设置的优先级对活动和睡眠应用的数据进行去重计算,您仍然可以构建自己的逻辑,为每个写入该数据的应用单独计算数据。
Health Connect 仅对活动和睡眠数据类型进行去重处理,显示的数据总计是聚合 API 执行去重后的值。这些总计显示了步数和距离数据存在的最近完整一天。对于其他类型的应用,Health Connect 中的数据总计会显示所有此类应用的组合总数。
后台读取
您可以请求您的应用在后台运行并从 Health Connect 读取数据。如果您请求后台读取权限,您的用户可以授予您的应用在后台读取数据的权限。
按记录支持的聚合数据类型
此表列出了 Health Connect 记录支持的所有聚合数据类型。