Чтение агрегированных данных

Агрегация данных в Health Connect включает в себя базовые агрегации и агрегацию данных по сегментам. Следующие рабочие процессы показывают, как выполнить оба варианта.

Базовая агрегация

Чтобы применить базовую агрегацию к вашим данным, используйте aggregate функцию объекта HealthConnectClient . Она принимает объект 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
    }
}

Ограничения чтения

По умолчанию все приложения могут считывать данные из Health Connect за период до 30 дней до момента первого предоставления какого-либо разрешения.

Если вам необходимо расширить разрешения на чтение за пределы ограничений по умолчанию , запросите разрешение PERMISSION_READ_HEALTH_DATA_HISTORY . В противном случае, без этого разрешения, попытка чтения записей старше 30 дней приведёт к ошибке.

История разрешений для удаленного приложения

Если пользователь удалит ваше приложение, все разрешения, включая разрешение на просмотр истории, будут отозваны. Если пользователь переустановит ваше приложение и снова предоставит разрешение, будут применены те же ограничения по умолчанию , и ваше приложение сможет считывать данные из Health Connect за период до 30 дней до этой новой даты.

Например, предположим, что пользователь удалил ваше приложение 10 мая 2023 года, а затем переустановил его 15 мая 2023 года и предоставил разрешения на чтение. Самая ранняя дата, с которой ваше приложение теперь по умолчанию может читать данные, — 15 апреля 2023 года .

Агрегированные данные, на которые влияют выбранные пользователем приоритеты приложений

Конечные пользователи могут устанавливать приоритет для приложений «Сон» и «Активность», интегрированных с Health Connect. Изменять эти списки приоритетов могут только конечные пользователи. При выполнении агрегированного чтения API Aggregate учитывает все дублирующиеся данные и сохраняет только данные из приложения с наивысшим приоритетом. Дублирующиеся данные могут существовать, если у пользователя одновременно используются несколько приложений, записывающих одни и те же данные, например, количество сделанных шагов или пройденное расстояние.

Информацию о том, как конечные пользователи могут расставить приоритеты для своих приложений, см. в разделе Управление данными Health Connect .

Пользователь может добавлять или удалять приложения, а также изменять их приоритеты. Пользователь может удалить приложение, которое записывает дублирующие данные, чтобы итоговые данные на экране Health Connect соответствовали данным приложения, которому он присвоил наивысший приоритет. Итоговые данные обновляются в режиме реального времени.

Несмотря на то, что API Aggregate вычисляет данные приложений Activity и Sleep, исключая дубликаты данных в соответствии с установленными пользователем приоритетами, вы все равно можете создать собственную логику для отдельного вычисления данных для каждого приложения, записывающего эти данные.

Health Connect дедуплицирует только данные по типам «Активность» и «Сон», а отображаемые итоговые данные представляют собой значения после дедупликации, выполненной API Aggregate. Эти итоговые данные отражают последние полные сутки, за которые имеются данные о количестве шагов и пройденном расстоянии. Для других типов приложений общее количество всех таких приложений отображается в итоговых данных Health Connect.

Фоновые чтения

Вы можете запросить запуск своего приложения в фоновом режиме и чтение данных из Health Connect. Если вы запросите разрешение на фоновое чтение , ваш пользователь сможет предоставить приложению доступ к чтению данных в фоновом режиме.

Поддерживаемые агрегированные типы данных по записи

В этой таблице перечислены все поддерживаемые агрегированные типы данных по записям 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 , TRANS_FAT_TOTAL , TOTAL_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