集計データを読み取る

ヘルスコネクトの集計データには、基本的な集計とバケットへのデータの集計があります。以下のワークフローでは、この 2 つの集計を行う方法について説明します。

基本的な集計

データに対して基本的な集計を行うには、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
    }
}

バケット

ヘルスコネクトでは、データをバケットに集計することもできます。使用できるバケットには、durationperiod の 2 種類があります。

呼び出されると、バケットのリストが返されます。リストがスパースになる可能性があるため、バケットにデータが含まれていない場合、バケットはリストに含まれません。

Duration

この場合、集計されたデータは一定の時間内(1 分、1 時間など)でバケットに分割されます。データをバケットに集約するには、aggregateGroupByDuration を使用します。これは、指標タイプ、時間範囲、Duration をパラメータとして取る AggregateGroupByDurationRequest オブジェクトを受け入れます。

ステップを分ごとのバケットで集計する例を以下に示します。

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

Period

この場合、集計されたデータは日付ベースの期間内(1 週間、1 か月など)でバケットに分割されます。データをバケットに集約するには、aggregateGroupByPeriod を使用します。これは、指標タイプ、時間範囲、Period をパラメータとして取る AggregateGroupByPeriodRequest オブジェクトを受け入れます。

ステップを月ごとのバケットで集計する例を以下に示します。

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 日間の制限

アプリは、最初に権限が付与された日の 30 日前までのデータをヘルスコネクトから読み取れます。

ただし、ユーザーがアプリを削除すると、権限履歴は失われます。ユーザーがアプリを再インストールして権限を再度付与すると、その新しい日付から最大 30 日間遡って、アプリがヘルスコネクトからデータを読み取れます。

30 日間の例

ユーザーが 2023 年 3 月 30 日に初めてアプリに読み取り権限を許可した場合、アプリは 2023 年 2 月 28 日以降のデータを読み取れます。

その後、ユーザーは 2023 年 5 月 10 日にアプリを削除しました。ユーザーは 2023 年 5 月 15 日にアプリを再インストールし、読み取り権限を許可しました。この場合、アプリは 2023 年 4 月 15 日以降のデータを読み取れます。

30 日以上前のデータを読み取る

30 日以上前のデータを読み取る場合は、PERMISSION_READ_HEALTH_DATA_HISTORY 権限を使用する必要があります。この権限がないと、30 日を超える単一レコードの読み取りを試みるとエラーが発生します。また、いずれかの期間リクエストを使用して 30 日より古いデータを読み取ることもできません。

ユーザーが選択したアプリの優先度によって影響を受ける集計データ

エンドユーザーは、ヘルスコネクトと統合した睡眠アプリとアクティビティ アプリの優先度を設定できます。これらの優先リストを変更できるのはエンドユーザーのみです。集計読み取りを実行すると、Aggregate API は重複データを考慮し、優先度が最も高いアプリのデータのみを保持します。ユーザーが複数のアプリを使用して、同じ種類のデータ(歩数や移動距離など)を同時に書き込むと、重複データが発生する可能性があります。

エンドユーザーがアプリの優先順位を設定する方法については、ヘルスコネクト データを管理するをご覧ください。

ユーザーはアプリの追加や削除、優先度の変更を行うことができます。ユーザーは、重複するデータを書き込むアプリを削除して、ヘルスコネクト画面のデータの合計が、優先度を最も高く設定したアプリと一致するようにしたい場合があります。データの合計はリアルタイムで更新されます。

Aggregate API は、ユーザーが優先度を設定した方法に応じてデータを重複除去してアクティビティ アプリと睡眠アプリのデータを計算しますが、独自のロジックを構築して、データを書き込むアプリごとにデータを個別に計算することもできます。

ヘルスコネクトで重複除去されるのは、アクティビティと睡眠のデータ型のみです。表示されるデータの合計は、Aggregate API によって重複除去が行われた後の値です。これらの合計には、歩数と距離のデータが存在する直近の 1 日分が含まれます。他のタイプのアプリについては、ヘルスコネクトのデータの合計に、そのようなアプリの合計数が表示されます。

バックグラウンドでの読み取り

アプリをバックグラウンドで実行し、ヘルスコネクトからデータを読み取るようにリクエストできます。バックグラウンド読み取り権限をリクエストすると、ユーザーはアプリにバックグラウンドでデータを読み取るアクセス権を付与できます。