Ler dados agregados

A agregação de dados no Conexão Saúde inclui agregações básicas ou dados agregados em intervalos. Os fluxos de trabalho abaixo mostram como fazer ambos.

Agregação básica

Para usar a agregação básica nos dados, use a função aggregate no objeto HealthConnectClient. Ela aceita um objeto AggregateRequest em que você adiciona os tipos de métricas e o período como parâmetros. A forma como os agregados básicos são chamados depende dos tipos de métricas usados.

Agregação cumulativa

A agregação cumulativa calcula o valor total.

O exemplo a seguir mostra como agregar um tipo de dados:

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
}

Filtrar por origem de dados

Também é possível filtrar dados agregados pela origem. Por exemplo, incluindo apenas dados gravados por um app específico.

O exemplo a seguir mostra como usar dataOriginFilter e AggregateRequest para agregar etapas de um app específico:

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

Agregação estatística

A agregação estatística calcula os valores mínimo, máximo ou médio de registros com amostras.

O exemplo abaixo mostra como usar a agregação estatística:

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
}

Intervalos

A Conexão Saúde também permite agregar dados em buckets. Os dois tipos de buckets que podem ser usados incluem duração e período.

Depois de chamados, eles retornam uma lista de buckets. A lista pode ser esparsa. Portanto, um intervalo não será incluído na lista se não contiver dados.

Duração

Nesse caso, os dados agregados são divididos em intervalos em um período fixo, como um minuto ou uma hora. Para agregar dados em intervalos, use aggregateGroupByDuration. Ele aceita um AggregateGroupByDurationRequest objeto em que você adiciona os tipos de métrica, o intervalo de tempo e o Duration como parâmetros. É possível usar pares de Instant ou LocalDateTime objetos para startTime e endTime em TimeRangeFilter.

Confira a seguir um exemplo de agregação de passos em intervalos de um minuto:

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

Período

Nesse caso, os dados agregados são divididos em intervalos em um período baseado em data, como uma semana ou um mês. Para agregar dados em intervalos, use aggregateGroupByPeriod. Ele aceita um objeto AggregateGroupByPeriodRequest em que você adiciona os tipos de métrica, o intervalo de tempo e o Period como parâmetros.

Confira a seguir um exemplo de agregação de etapas em intervalos mensais:

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

Restrições de leitura

Por padrão, todos os aplicativos podem ler dados da Conexão Saúde registrados até 30 dias antes da permissão ser concedida.

Se você precisar estender as permissões de leitura além de qualquer uma das restrições padrão, solicite a PERMISSION_READ_HEALTH_DATA_HISTORY. Caso contrário, sem essa permissão, uma tentativa de ler registros com mais de 30 dias resultará em um erro.

Histórico de permissões de um app excluído

Se um usuário excluir seu app, todas as permissões, incluindo a de histórico, serão revogadas. Se o usuário reinstalar o app e conceder a permissão novamente, as mesmas restrições padrão serão aplicadas, e o app poderá ler dados da Conexão Saúde registrados até 30 dias antes dessa nova data.

Por exemplo, suponha que o usuário exclua seu app em 10 de maio de 2023, reinstale-o em 15 de maio de 2023 e conceda permissões de leitura. A data mais antiga em que seu app pode ler dados por padrão é 15 de abril de 2023.

Dados agregados afetados pelas prioridades de apps selecionadas pelo usuário

Os usuários finais podem definir a prioridade dos apps de sono e atividade que integraram à Conexão Saúde. Somente os usuários finais podem alterar essas listas de prioridade. Ao realizar uma leitura agregada, a API Aggregate considera todos os dados duplicados e mantém apenas os dados do app com a maior prioridade. Dados duplicados podem existir se o usuário tiver vários apps gravando o mesmo tipo de dados, como o número de passos dados ou a distância percorrida, ao mesmo tempo.

Figura mostrando &quot;Reordenar prioridades de apps&quot;
Figura 1: reordenar as prioridades dos apps

Figura mostrando a reordenação das prioridades dos apps

Para informações sobre como os usuários finais podem priorizar os apps, consulte Gerenciar dados da Conexão Saúde.

O usuário pode adicionar ou remover apps, bem como mudar as prioridades. Um usuário pode querer remover um app que está gravando dados duplicados para que os totais de dados na tela da Conexão Saúde sejam idênticos ao app que recebeu a maior prioridade. Os totais de dados são atualizados em tempo real.

Embora a API Aggregate calcule os dados dos apps de atividade e sono desduplicando os dados de acordo com a forma como o usuário definiu as prioridades, ainda é possível criar sua própria lógica para calcular os dados separadamente para cada app que grava esses dados.

Somente os tipos de dados de atividade e dados de sono são desduplicados pela Conexão Saúde, e os totais de dados mostrados são os valores após a desduplicação ser realizada pela API Aggregate. Esses totais mostram o dia completo mais recente em que há dados de passos e distância. Para outros tipos de dados, os resultados agregados combinam todos os dados do tipo na Conexão Saúde de todos os apps que gravaram os dados.

Leituras em segundo plano

É possível solicitar que o aplicativo seja executado em segundo plano e leia dados da Conexão Saúde. Se você solicitar a permissão de leitura em segundo plano, o usuário poderá conceder ao app acesso para ler dados em segundo plano.

Tipos de dados agregados aceitos por registro

Esta tabela lista todos os tipos de dados agregados aceitos pelo registro da Conexão Saúde.

Tabela: tipos de dados agregados aceitos por registro
Gravar Tipo de dados agregados
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