Агрегирование данных в 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
. Он принимает объект 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-дневное ограничение
Приложения могут считывать данные из 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 дней, используя один из запросов временного диапазона.