读取聚合数据

在 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 记录支持的所有聚合数据类型。

记录 聚合数据类型
消耗的活动卡路里 ACTIVE_CALORIES_TOTAL
基础代谢率 BASAL_CALORIES_TOTAL
血压 DIASTOLIC_AVG, DIASTOLIC_MAX, DIASTOLIC_MIN, SYSTOLIC_AVG, SYSTOLIC_MAX, SYSTOLIC_MIN
骑行踏频 RPM_AVG, RPM_MAX, RPM_MIN
距离 DISTANCE_TOTAL
海拔增益 ELEVATION_GAINED_TOTAL
运动会话 EXERCISE_DURATION_TOTAL
爬楼层数 FLOORS_CLIMBED_TOTAL
心率 BPM_AVG, BPM_MAX, BPM_MIN, MEASUREMENTS_COUNT
身高 HEIGHT_AVG, HEIGHT_MAX, HEIGHT_MIN
水合作用 VOLUME_TOTAL
正念会话 MINDFULNESS_DURATION_TOTAL
营养 BIOTIN_TOTAL, CAFFEINE_TOTAL, CALCIUM_TOTAL, CHLORIDE_TOTAL, CHOLESTEROL_TOTAL, CHROMIUM_TOTAL, COPPER_TOTAL, DIETARY_FIBER_TOTAL, ENERGY_FROM_FAT_TOTAL, ENERGY_TOTAL, FOLATE_TOTAL, FOLIC_ACID_TOTAL, IODINE_TOTAL, IRON_TOTAL, MAGNESIUM_TOTAL, MANGANESE_TOTAL, MOLYBDENUM_TOTAL, MONOUNSATURATED_FAT_TOTAL, NIACIN_TOTAL, PANTOTHENIC_ACID_TOTAL, PHOSPHORUS_TOTAL, POLYUNSATURATED_FAT_TOTAL, POTASSIUM_TOTAL, PROTEIN_TOTAL, RIBOFLAVIN_TOTAL, SATURATED_FAT_TOTAL, SELENIUM_TOTAL, SODIUM_TOTAL, SUGAR_TOTAL, THIAMIN_TOTAL, TOTAL_CARBOHYDRATE_TOTAL, TOTAL_FAT_TOTAL, TRANS_FAT_TOTAL, UNSATURATED_FAT_TOTAL, VITAMIN_A_TOTAL, VITAMIN_B12_TOTAL, VITAMIN_B6_TOTAL, VITAMIN_C_TOTAL, VITAMIN_D_TOTAL, VITAMIN_E_TOTAL, VITAMIN_K_TOTAL, ZINC_TOTAL
功率 POWER_AVG, POWER_MAX, POWER_MIN
静息心率 BPM_AVG, BPM_MAX, BPM_MIN
皮肤温度 TEMPERATURE_DELTA_AVG, TEMPERATURE_DELTA_MAX, TEMPERATURE_DELTA_MIN
睡眠会话 SLEEP_DURATION_TOTAL
速度 SPEED_AVG, SPEED_MAX, SPEED_MIN
步数 COUNT_TOTAL
步频 RATE_AVG, RATE_MAX, RATE_MIN
消耗的总卡路里 ENERGY_TOTAL
体重 WEIGHT_AVG, WEIGHT_MAX, WEIGHT_MIN
轮椅推动次数 COUNT_TOTAL