Leggere dati aggregati

L'aggregazione dei dati in Health Connect include aggregazioni di base o l'aggregazione dei dati in bucket. I seguenti flussi di lavoro mostrano come fare entrambe le cose.

Aggregazione di base

Per utilizzare l'aggregazione di base sui dati, utilizza la funzione aggregate sull'oggetto HealthConnectClient. Accetta un oggetto AggregateRequest in cui aggiungi i tipi di metrica e l'intervallo di tempo come parametri. Il modo in cui vengono chiamati gli aggregati di base dipende dai tipi di metriche utilizzati.

Aggregazione cumulativa

L'aggregazione cumulativa calcola il valore totale.

Il seguente esempio mostra come aggregare i dati per un tipo di dati:

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
}

Filtrare per origine dati

Puoi anche filtrare i dati aggregati in base alla loro origine. Ad esempio, includendo solo i dati scritti da un'app specifica.

L'esempio seguente mostra come utilizzare dataOriginFilter e AggregateRequest per aggregare i passi di un'app specifica:

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

Aggregazione statistica

L'aggregazione statistica calcola i valori minimi, massimi o medi dei record con campioni.

L'esempio seguente mostra come utilizzare l'aggregazione statistica:

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
}

Bucket

Connessione Salute può anche consentirti di aggregare i dati in segmenti. I due tipi di bucket che puoi utilizzare includono durata e periodo.

Una volta chiamati, restituiscono un elenco di bucket. Tieni presente che l'elenco può essere sparso, quindi un bucket non è incluso nell'elenco se non contiene dati.

Durata

In questo caso, i dati aggregati vengono suddivisi in bucket entro un periodo di tempo fisso, ad esempio un minuto o un'ora. Per aggregare i dati in bucket, utilizza aggregateGroupByDuration. Accetta un oggetto AggregateGroupByDurationRequest in cui aggiungi i tipi di metrica, l'intervallo di tempo e Duration come parametri. Puoi utilizzare coppie di oggetti Instant o LocalDateTime per startTime e endTime in TimeRangeFilter.

Di seguito è riportato un esempio di aggregazione dei passi in bucket di un 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
    }
}

Periodo

In questo caso, i dati aggregati vengono suddivisi in bucket all'interno di un periodo di tempo basato sulla data, ad esempio una settimana o un mese. Per aggregare i dati in bucket, utilizza aggregateGroupByPeriod. Accetta un oggetto AggregateGroupByPeriodRequest in cui aggiungi i tipi di metrica, l'intervallo di tempo e Period come parametri.

Di seguito è riportato un esempio di aggregazione dei passaggi in bucket mensili:

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

Limitazioni di lettura

Per impostazione predefinita, tutte le applicazioni possono leggere i dati da Connessione Salute fino a 30 giorni prima del momento in cui è stata concessa la prima autorizzazione.

Se hai bisogno di estendere le autorizzazioni in lettura oltre lelimitazioni predefinite, richiedi PERMISSION_READ_HEALTH_DATA_HISTORY. In caso contrario, senza questa autorizzazione, ogni tentativo di lettura dei record più vecchi di 30 giorni genererà un errore.

Cronologia delle autorizzazioni per un'app eliminata

Se un utente elimina la tua app, tutte le autorizzazioni, inclusa quella della cronologia, vengono revocate. Se l'utente reinstalla la tua app e concede nuovamente l'autorizzazione, si applicano le stesse limitazioni predefinite e la tua app può leggere i dati di Connessione Salute fino a 30 giorni precedenti a questa nuova data.

Ad esempio, supponiamo che l'utente elimini la tua app il 10 maggio 2023 e poi la reinstalli il 15 maggio 2023, concedendo le autorizzazioni di lettura. La data più recente a partire dalla quale la tua app può leggere i dati per impostazione predefinita è il 15 aprile 2023.

Aggregare i dati interessati dalle priorità delle app selezionate dall'utente

Gli utenti finali possono impostare la priorità per le app Sonno e Attività che hanno integrato con Health Connect. Solo gli utenti finali possono modificare queste liste di priorità. Quando esegui una lettura aggregata, l'API Aggregate tiene conto di eventuali dati duplicati e conserva solo i dati dell'app con la priorità più alta. Potrebbero esistere dati duplicati se l'utente ha più app che scrivono lo stesso tipo di dati, ad esempio il numero di passi fatti o la distanza percorsa, contemporaneamente.

Figura che mostra il riordino delle priorità delle app
Figura 1: riordina le priorità delle app

Figura che mostra il riordino delle priorità delle app

Per informazioni su come gli utenti finali possono dare la priorità alle proprie app, vedi Gestire i dati di Health Connect.

L'utente può aggiungere o rimuovere app, nonché modificarne le priorità. Un utente potrebbe voler rimuovere un'app che scrive dati duplicati in modo che i totali dei dati nella schermata di Health Connect siano identici a quelli dell'app a cui ha assegnato la priorità più alta. I totali dei dati vengono aggiornati in tempo reale.

Anche se l'API Aggregate calcola i dati delle app Attività e Sonno deduplicandoli in base alle priorità impostate dall'utente, puoi comunque creare una logica personalizzata per calcolare i dati separatamente per ogni app che li scrive.

Solo i tipi di dati Attività e dati relativi al sonno vengono deduplicati da Health Connect e i totali dei dati visualizzati sono i valori dopo l'esecuzione della deduplicazione da parte dell'API Aggregate. Questi totali mostrano l'ultimo giorno intero in cui sono presenti dati relativi a passi e distanza. Per altri tipi di dati, i risultati aggregati combinano tutti i dati del tipo in Connessione Salute di tutte le app che hanno scritto i dati.

Letture in background

Puoi richiedere che la tua applicazione venga eseguita in background e legga i dati da Health Connect. Se richiedi l'autorizzazione Lettura in background, l'utente può concedere alla tua app l'accesso per leggere i dati in background.

Tipi di dati aggregati supportati per record

Questa tabella elenca tutti i tipi di dati aggregati supportati dal record di Health Connect.

Tabella: tipi di dati aggregati supportati per record
Registra Tipo di dati aggregati
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