在 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
}
}
按数据来源过滤
您还可以按来源过滤汇总数据。例如,仅包含由特定应用写入的数据。
以下示例展示了如何使用 dataOriginFilter
和 AggregateRequest
汇总来自特定应用的数据:
suspend fun aggregateStepsFromSpecificApp(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant,
appPackageName: String
) {
try {
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = setOf(DataOrigin(appPackageName))
)
)
// The result may be null if no data is available in the time range
val totalSteps = response[StepsRecord.COUNT_TOTAL] ?: 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
}
}
阅读限制
默认情况下,所有应用都可以读取在首次授予任何权限前最多 30 天的健康数据共享数据。
如果您需要将读取权限扩展到超出任何默认限制的范围,请请求 PERMISSION_READ_HEALTH_DATA_HISTORY
。
否则,如果没有此权限,尝试读取超过 30 天的记录会导致错误。
已删除应用的权限记录
如果用户删除您的应用,所有权限(包括历史记录权限)都会被撤消。如果用户重新安装您的应用并再次授予权限,则适用相同的默认限制,并且您的应用可以读取从该新日期最多回推 30 天的健康数据共享数据。
例如,假设用户在 2023 年 5 月 10 日删除了您的应用,然后在 2023 年 5 月 15 日重新安装该应用并授予读取权限。现在,您的应用默认可读取的数据最早可追溯至 2023 年 4 月 15 日。
受用户选择的应用优先级影响的汇总数据
最终用户可以为已与“健康数据共享”集成的睡眠和活动应用设置优先级。只有最终用户可以更改这些优先级列表。当您执行汇总读取时,Aggregate API 会考虑所有重复数据,并仅保留优先级最高的应用中的数据。如果用户同时有多个应用写入相同类型的数据(例如步数或行进距离),则可能会出现重复数据。
如需了解最终用户如何确定应用的优先级,请参阅管理“健康数据共享”数据。
用户可以添加或移除应用,也可以更改应用的优先级。用户可能想要移除正在写入重复数据的应用,以便“健康数据共享”屏幕上的数据总值与他们已给予最高优先级的应用中的数据总值相同。数据总数会实时更新。
虽然 Aggregate API 会根据用户设置的优先级对 Activity 和 Sleep 应用的数据进行去重,从而计算出相应数据,但您仍然可以构建自己的逻辑,分别计算每个写入数据的应用的数据。
健康数据共享仅会对活动和睡眠数据类型进行去重,并且显示的汇总数据是 Aggregate API 执行去重后的值。这些总计值显示的是最近的完整一天(有步数和距离数据)。对于其他类型的应用,所有此类应用的总数会显示在健康数据共享中的总计数据中。
后台读取
您可以请求让应用在后台运行并从“健康数据共享”读取数据。如果您请求后台读取权限,用户可以授予您的应用在后台读取数据的权限。
按记录划分的支持的汇总数据类型
下表列出了健康数据共享记录支持的所有汇总数据类型。