讀取匯總資料

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
    }
}

依資料來源篩選

您也可以依來源篩選匯總資料。舉例來說,只納入特定應用程式寫入的資料。

以下範例說明如何使用 dataOriginFilterAggregateRequest 匯總特定應用程式的步數:

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
    }
}

Bucket

健康資料同步也能讓您將資料匯總成「值區」。您可以使用兩種類型的值區,包括時間長度時段

呼叫這些值區之後,系統會傳回值區清單。請注意,這份清單的項目可以不用連續,因此如果值區中沒有任何資料,就不會列入清單。

時間長度

在此情況下,系統會將一段固定時間 (例如一分鐘或一小時) 內的匯總資料分割為多個值區。如要將資料匯總成值區,請使用 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 會根據使用者設定的優先順序,對活動和睡眠應用程式的資料進行重複資料刪除,您仍可建立自己的邏輯,分別計算每個寫入資料的應用程式資料。

健康資料同步只會移除重複的「活動」和「睡眠」資料類型,而顯示的資料總計值是匯總 API 執行去重複作業後的值。這些總數顯示最近一天的完整資料,包括步數和距離。如果是其他類型的應用程式,Health Connect 的資料總計會顯示所有這類應用程式的總數。

背景讀取

您可以要求應用程式在背景執行,並從「健康資料同步」讀取資料。如果您要求「背景讀取」權限,使用者可以授予應用程式在背景讀取資料的權限。

依記錄支援的匯總資料類型

下表列出「健康資料同步」記錄支援的所有匯總資料類型。

錄影 匯總資料類型
ActiveCaloriesBurned ACTIVE_CALORIES_TOTAL
BasalMetabolicRate BASAL_CALORIES_TOTAL
BloodPressure DIASTOLIC_AVG DIASTOLIC_MAX DIASTOLIC_MIN SYSTOLIC_AVG SYSTOLIC_MAX SYSTOLIC_MIN
CyclingPedalingCadence RPM_AVG, RPM_MAX, RPM_MIN
Distance DISTANCE_TOTAL
ElevationGained ELEVATION_GAINED_TOTAL
ExerciseSession EXERCISE_DURATION_TOTAL
FloorsClimbed FLOORS_CLIMBED_TOTAL
HeartRate BPM_AVG, BPM_MAX, BPM_MIN, MEASUREMENTS_COUNT
Height HEIGHT_AVG, HEIGHT_MAX, HEIGHT_MIN
Hydration VOLUME_TOTAL
MindfulnessSession MINDFULNESS_DURATION_TOTAL
Nutrition 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 POWER_AVG, POWER_MAX, POWER_MIN
RestingHeartRate BPM_AVG, BPM_MAX, BPM_MIN
SkinTemperature TEMPERATURE_DELTA_AVG, TEMPERATURE_DELTA_MAX, TEMPERATURE_DELTA_MIN
SleepSession SLEEP_DURATION_TOTAL
Speed SPEED_AVG, SPEED_MAX, SPEED_MIN
Steps COUNT_TOTAL
StepsCadence RATE_AVG, RATE_MAX, RATE_MIN
TotalCaloriesBurned ENERGY_TOTAL
Weight WEIGHT_AVG, WEIGHT_MAX, WEIGHT_MIN
WheelchairPushes COUNT_TOTAL