Агрегирование данных в 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
}
}
Статистическое агрегирование
Статистическая агрегация вычисляет минимальные, максимальные или средние значения записей с выборками.
В следующем примере показано, как использовать статистическое агрегирование:
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
, используйтеагрегатGroupByDuration. Он принимает объект 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
, используйтеагрегатGroupByPeriod. Он принимает объект 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-дневное ограничение
Приложения могут считывать данные из Health Connect за 30 дней до момента первого предоставления разрешения.
Однако если пользователь удаляет ваше приложение, история разрешений теряется. Если пользователь переустановит ваше приложение и снова предоставит разрешение, ваше приложение сможет считывать данные из Health Connect за 30 дней до этой новой даты.
пример 30-дневного периода
Если пользователь впервые предоставил разрешение на чтение вашему приложению 30 марта 2023 года, самые ранние данные, которые ваше приложение сможет прочитать, будут начиная с 28 февраля 2023 года .
Затем пользователь удаляет ваше приложение 10 мая 2023 г. Пользователь решает переустановить его 15 мая 2023 г. и предоставить разрешение на чтение. Самая ранняя дата, с которой ваше приложение теперь может считывать данные, — 15 апреля 2023 года .
Чтение данных старше 30 дней.
Если вы хотите прочитать данные старше 30 дней, вы должны использовать разрешение PERMISSION_READ_HEALTH_DATA_HISTORY
. Без этого разрешения попытка прочитать одну запись старше 30 дней приведет к ошибке. Вы также не можете прочитать данные старше 30 дней, используя один из запросов временного диапазона.
Совокупные данные, на которые влияют приоритеты приложений, выбранных пользователем.
Конечные пользователи могут устанавливать приоритет для приложений «Сон» и «Активность», которые они интегрировали с Health Connect. Только конечные пользователи могут изменять эти списки приоритетов. Когда вы выполняете агрегатное чтение, Aggregate API учитывает любые повторяющиеся данные и сохраняет только данные из приложения с наивысшим приоритетом. Дублирующиеся данные могут существовать, если у пользователя есть несколько приложений, записывающих одни и те же данные, например количество пройденных шагов или пройденное расстояние, одновременно.
Информацию о том, как конечные пользователи могут расставлять приоритеты для своих приложений, см. в разделе «Управление данными Health Connect» .
Пользователь может добавлять или удалять приложения, а также изменять их приоритеты. Пользователь может захотеть удалить приложение, которое записывает повторяющиеся данные, чтобы общие данные на экране Health Connect были идентичны приложению, которому он придал наивысший приоритет. Итоговые данные обновляются в режиме реального времени.
Несмотря на то, что Aggregate API вычисляет данные приложений «Активность» и «Сон» путем дедупликации данных в соответствии с тем, как пользователь установил приоритеты, вы все равно можете создать свою собственную логику для расчета данных отдельно для каждого приложения, записывающего эти данные.
Health Connect выполняет дедупликацию только типов данных «Активность» и «Сон», а отображаемые итоговые данные представляют собой значения после выполнения дедупликации с помощью Aggregate API. Эти итоговые значения показывают последний полный день, когда существуют данные о шагах и расстоянии. Для других типов приложений общее количество всех таких приложений отображается в итоговых данных Health Connect.
Фон читает
Вы можете запросить, чтобы ваше приложение работало в фоновом режиме и считывало данные из Health Connect. Если вы запрашиваете разрешение на чтение в фоновом режиме , ваш пользователь может предоставить вашему приложению доступ для чтения данных в фоновом режиме.