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

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

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

Для применения базовой агрегации к вашим данным используйте функцию aggregate объекта HealthConnectClient . Она принимает объект AggregateRequest , в качестве параметров которого вы указываете типы метрик и временной диапазон. Способ вызова базовой агрегации зависит от используемых типов метрик.

Кумулятивное агрегирование

Кумулятивное агрегирование вычисляет общую сумму.

В следующем примере показано, как агрегировать данные по определенному типу данных:

suspend fun readDistanceAggregate(startTime: Instant, endTime: Instant): Number {
    val response = healthConnectClient.aggregate(
        AggregateRequest(
            metrics = setOf(DistanceRecord.DISTANCE_TOTAL),
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )
    return response[DistanceRecord.DISTANCE_TOTAL]?.inMeters ?: 0L
}

Фильтрация по источнику данных

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

В следующем примере показано, как использовать 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 readHeartRateAggregate(startTime: Instant, endTime: Instant): Pair<Long, Long> {
    val response = healthConnectClient.aggregate(
        AggregateRequest(
            metrics = setOf(HeartRateRecord.BPM_MAX, HeartRateRecord.BPM_MIN),
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )
    val minimumHeartRate = response[HeartRateRecord.BPM_MIN] ?: 0L
    val maximumHeartRate = response[HeartRateRecord.BPM_MAX] ?: 0L

    return maximumHeartRate to minimumHeartRate
}

Ведра

Health Connect также позволяет объединять данные в группы . Можно использовать два типа групп: по продолжительности и по периодам .

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

Продолжительность

В этом случае агрегированные данные разбиваются на интервалы в пределах фиксированного промежутка времени, например, минуты или часа. Для агрегирования данных по интервалам используйте aggregateGroupByDuration . Он принимает объект AggregateGroupByDurationRequest , в который вы добавляете типы метрик, временной диапазон и Duration в качестве параметров. В качестве startTime и endTime в TimeRangeFilter можно использовать пары объектов Instant или LocalDateTime .

Ниже приведён пример объединения шагов в интервалы по минутам:

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] ?: 0L
        }
    } 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] ?: 0L
        }
    } 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 агрегирования учитывает любые дублирующиеся данные и сохраняет только данные из приложения с наивысшим приоритетом. Дублирующиеся данные могут существовать, если у пользователя одновременно запущено несколько приложений, записывающих данные одного и того же типа — например, количество пройденных шагов или пройденное расстояние.

Рисунок, показывающий приоритеты приложения «Переупорядочить».
Рисунок 1 : Изменение приоритетов приложений

Рисунок, показывающий приоритеты приложений для переупорядочивания.

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

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

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

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

Справочная информация

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

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

В этой таблице перечислены все поддерживаемые типы агрегированных данных для каждой записи Health Connect.

Таблица: Поддерживаемые типы агрегированных данных по записям
Записывать Агрегированный тип данных
ActiveCaloriesBurnedRecord ACTIVE_CALORIES_TOTAL
ActivityIntensityRecord DURATION_TOTAL , INTENSITY_MINUTES_TOTAL , MODERATE_DURATION_TOTAL , VIGOROUS_DURATION_TOTAL
BasalMetabolicRateRecord BASAL_CALORIES_TOTAL
BloodPressureRecord DIASTOLIC_AVG , DIASTOLIC_MAX , DIASTOLIC_MIN , SYSTOLIC_AVG , SYSTOLIC_MAX , SYSTOLIC_MIN
CyclingPedalingCadenceRecord RPM_AVG , RPM_MAX , RPM_MIN
DistanceRecord DISTANCE_TOTAL
ElevationGainedRecord ELEVATION_GAINED_TOTAL
ExerciseSessionRecord EXERCISE_DURATION_TOTAL
FloorsClimbedRecord FLOORS_CLIMBED_TOTAL
HeartRateRecord BPM_AVG , BPM_MAX , BPM_MIN , MEASUREMENTS_COUNT
HeightRecord HEIGHT_AVG , HEIGHT_MAX , HEIGHT_MIN
HydrationRecord VOLUME_TOTAL
MindfulnessSessionRecord MINDFULNESS_DURATION_TOTAL
NutritionRecord 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
PowerRecord POWER_AVG , POWER_MAX , POWER_MIN
RestingHeartRateRecord BPM_AVG , BPM_MAX , BPM_MIN
SkinTemperatureRecord TEMPERATURE_DELTA_AVG , TEMPERATURE_DELTA_MAX , TEMPERATURE_DELTA_MIN
SleepSessionRecord SLEEP_DURATION_TOTAL
SpeedRecord SPEED_AVG , SPEED_MAX , SPEED_MIN
StepsRecord COUNT_TOTAL
StepsCadenceRecord RATE_AVG , RATE_MAX , RATE_MIN
TotalCaloriesBurnedRecord ENERGY_TOTAL
WeightRecord WEIGHT_AVG , WEIGHT_MAX , WEIGHT_MIN
WheelchairPushesRecord COUNT_TOTAL