Leggere dati aggregati

L'aggregazione dei dati in Connessione Salute 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 nome degli aggregati di base dipende dai tipi di metrica utilizzati.

Aggregazione cumulativa

L'aggregazione cumulativa calcola il valore totale.

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

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

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.

Il seguente esempio mostra come utilizzare l'aggregazione statistica:

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

Bucket

Connessione Salute può anche consentirti di aggregare i dati in bucket. 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.

Di seguito è riportato un esempio di aggregazione dei passi in bucket della durata 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]
        }
    } catch (e: Exception) {
        // Run error handling here
    }
}

Punto

In questo caso, i dati aggregati vengono suddivisi in bucket in 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]
        }
    } 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 della concessione di qualsiasi autorizzazione.

Se hai bisogno di estendere le autorizzazioni di lettura oltre le limitazioni predefinite, richiedi l'PERMISSION_READ_HEALTH_DATA_HISTORY. In caso contrario, senza questa autorizzazione, un tentativo di leggere record più vecchi di 30 giorni genera 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 prima di questa nuova data.

Ad esempio, supponiamo che l'utente elimini la tua app il 10 maggio 2023, la reinstalli il 15 maggio 2023 e conceda 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 Connessione Salute. 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.

Per informazioni su come gli utenti finali possono dare la priorità alle loro app, vedi Gestire i dati di Connessione Salute.

L'utente può aggiungere o rimuovere app e modificarne le priorità. Un utente potrebbe voler rimuovere un'app che scrive dati duplicati in modo che i totali dei dati nella schermata di Connessione Salute 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 a come l'utente ha impostato le priorità, puoi comunque creare la tua logica per calcolare i dati separatamente per ogni app che scrive i dati.

Solo i tipi di dati Attività e Sonno vengono deduplicati da Connessione Salute 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 completo in cui sono presenti dati relativi a passi e distanza. Per altri tipi di app, i numeri totali di tutte queste app combinate vengono mostrati nei totali dei dati in Connessione Salute.

Letture in background

Puoi richiedere che la tua applicazione venga eseguita in background e legga i dati da Connessione Salute. 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 Connessione Salute.

Registra Tipo di dati aggregati
ActiveCaloriesBurned ACTIVE_CALORIES_TOTAL
BasalMetabolicRate BASAL_CALORIES_TOTAL
BloodPressure DIASTOLIC_AVG, DIASTOLIC_MAX, DIASTOLIC_MIN, SYSTOLIC_AVG, SYSTOLIC_MAX, SYSTOLIC_MIN
CyclingPedalingCadence RPM_AVG, RPM_MAX, RPM_MIN
Distance DISTANCE_TOTAL
ElevationGained ELEVATION_GAINED_TOTAL
ExerciseSession EXERCISE_DURATION_TOTAL
FloorsClimbed FLOORS_CLIMBED_TOTAL
HeartRate BPM_AVG, BPM_MAX, BPM_MIN, MEASUREMENTS_COUNT
Height HEIGHT_AVG, HEIGHT_MAX, HEIGHT_MIN
Hydration VOLUME_TOTAL
MindfulnessSession MINDFULNESS_DURATION_TOTAL
Nutrition 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
Power POWER_AVG, POWER_MAX, POWER_MIN
RestingHeartRate BPM_AVG, BPM_MAX, BPM_MIN
SkinTemperature TEMPERATURE_DELTA_AVG, TEMPERATURE_DELTA_MAX, TEMPERATURE_DELTA_MIN
SleepSession SLEEP_DURATION_TOTAL
Speed SPEED_AVG, SPEED_MAX, SPEED_MIN
Steps COUNT_TOTAL
StepsCadence RATE_AVG, RATE_MAX, RATE_MIN
TotalCaloriesBurned ENERGY_TOTAL
Weight WEIGHT_AVG, WEIGHT_MAX, WEIGHT_MIN
WheelchairPushes COUNT_TOTAL