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

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

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 objeto AggregateGroupByDurationRequest em que você adiciona os tipos de métrica, o intervalo de tempo e o Duration como parâmetros.

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]
        }
    } 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]
        }
    } catch (e: Exception) {
        // Run error handling here
    }
}

Restrições de leitura

Por padrão, o app pode ler dados de até 30 dias com qualquer permissão concedida. Com a permissão PERMISSION_READ_HEALTH_DATA_HISTORY, o app pode ler dados com mais de 30 dias.

Restrição de 30 dias

Os aplicativos podem ler dados da Conexão Saúde registrados até 30 dias antes da permissão ser concedida.

No entanto, se um usuário excluir seu app, o histórico de permissões será perdido. Se o usuário reinstalar o app e conceder a permissão novamente, ele poderá ler dados da Conexão Saúde registrados até 30 dias antes dessa nova data.

Exemplo de 30 dias

Se um usuário concedeu permissão de leitura ao seu app pela primeira vez em 30 de março de 2023, os dados mais antigos que ele poderá ler serão de 28 de fevereiro de 2023 em diante.

Em seguida, o usuário exclui seu app em 10 de maio de 2023. O usuário decide reinstalá-lo em 15 de maio de 2023 e conceder permissão de leitura. A data mais antiga de que o app poderá ler dados será 15 de abril de 2023.

Ler dados com mais de 30 dias

Se você quiser ler dados com mais de 30 dias, use a permissão PERMISSION_READ_HEALTH_DATA_HISTORY. Sem essa permissão, uma tentativa de leitura de um único registro com mais de 30 dias resulta em um erro. Também não é possível ler dados com mais de 30 dias usando uma das solicitações de período.