Scrittura di dati

Questa guida illustra la procedura di scrittura o aggiornamento dei dati in Connessione Salute.

Configura la struttura dei dati

Prima di scrivere i dati, dobbiamo impostare i record. Per oltre 50 tipi di dati, ciascuno ha la propria struttura. Consulta la documentazione di riferimento per Jetpack per ulteriori dettagli sui tipi di dati disponibili.

Record di base

Il tipo di dati Steps in Connessione Salute acquisisce il numero di passi effettuati da un utente tra una lettura e l'altra. Il numero di passi rappresenta una misurazione comune tra le piattaforme per salute, fitness e benessere.

L'esempio seguente mostra come impostare i dati sul conteggio dei passi:

val stepsRecord = StepsRecord(
    count = 120,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

Record con unità di misura

Connessione Salute può memorizzare valori insieme alle loro unità di misura per fornire accuratezza. Un esempio è il tipo di dati di alimentazione, ampio e completo. Comprende una vasta gamma di campi nutritivi facoltativi, dai carboidrati totali alle vitamine. Ogni punto dati rappresenta le sostanze nutritive potenziali consumate come parte di un pasto o di un alimento.

In questo tipo di dati, tutti i nutrienti sono rappresentati in unità di Mass, mentre energy è rappresentato in un'unità di Energy.

L'esempio seguente mostra come impostare i dati nutrizionali per un utente che ha mangiato una banana:

val banana = NutritionRecord(
    name = "banana",
    energy = 105.0.kilocalories,
    dietaryFiber = 3.1.grams,
    potassium = 0.422.grams,
    totalCarbohydrate = 27.0.grams,
    totalFat = 0.4.grams,
    saturatedFat = 0.1.grams,
    sodium = 0.001.grams,
    sugar = 14.0.grams,
    vitaminB6 = 0.0005.grams,
    vitaminC = 0.0103.grams,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

Record con dati della serie

Connessione Salute può archiviare un elenco di dati della serie. Un esempio è il tipo di dati Frequenza cardiaca, che acquisisce una serie di campioni di battito cardiaco rilevati tra una lettura e l'altra.

In questo tipo di dati, il parametro samples è rappresentato da un elenco di campioni di frequenza cardiaca. Ogni esempio contiene un valore beatsPerMinute e un valore time.

L'esempio seguente mostra come impostare i dati della serie sulla frequenza cardiaca:

val heartRateRecord = HeartRateRecord(
    startTime = START_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endTime = END_TIME,
    endZoneOffset = END_ZONE_OFFSET,
    // records 10 arbitrary data, to replace with actual data
    samples = List(10) { index ->
        HeartRateRecord.Sample(
            time = START_TIME + Duration.ofSeconds(index.toLong()),
            beatsPerMinute = 100 + index.toLong(),
        )
    }
)

Scrittura di dati

Uno dei flussi di lavoro comuni in Connessione Salute è la scrittura di dati. Per aggiungere record, utilizza insertRecords.

L'esempio seguente mostra come scrivere dati per l'inserimento dei conteggi di passi:

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = START_TIME,
            endTime = END_TIME,
            startZoneOffset = START_ZONE_OFFSET,
            endZoneOffset = END_ZONE_OFFSET
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

Aggiorna dati

Se devi modificare uno o più record, soprattutto quando devi sincronizzare il datastore dell'app con i dati di Connessione Salute, puoi aggiornare questi dati. Esistono due modi per aggiornare i dati esistenti, che dipendono dall'identificatore utilizzato per trovare i record.

Metadati

Vale la pena esaminare prima la classe Metadata perché è necessaria quando si aggiornano i dati. Al momento della creazione, ogni Record in Connessione Salute ha un campo metadata. Le seguenti proprietà sono pertinenti per la sincronizzazione:

Proprietà Descrizione
id Ogni Record in Connessione Salute ha un valore id univoco.
Connessione integrità compila automaticamente questo campo quando inserisci un nuovo record.
lastModifiedTime Ogni Record tiene anche traccia dell'ultima volta che il record è stato modificato.
Connessione Salute lo compila automaticamente.
clientRecordId A ogni Record può essere associato un ID univoco da usare come riferimento nel datastore dell'app.
Questo valore viene fornito dalla tua app.
clientRecordVersion Se un record ha clientRecordId, clientRecordVersion può essere utilizzato per consentire ai dati di rimanere sincronizzati con la versione nel datastore dell'app.
Questo valore viene fornito dalla tua app.

Aggiorna tramite ID record

Per aggiornare i dati, prepara prima i record necessari. Se necessario, apporta eventuali modifiche ai record. Poi, chiama updateRecords per apportare le modifiche.

L'esempio seguente mostra come aggiornare i dati. A questo scopo, i valori di offset di ogni record vengono corretti in PST.

suspend fun updateSteps(
    healthConnectClient: HealthConnectClient,
    prevRecordStartTime: Instant,
    prevRecordEndTime: Instant
) {
    try {
        val request = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = StepsRecord::class,
                timeRangeFilter = TimeRangeFilter.between(
                    prevRecordStartTime,
                    prevRecordEndTime
                )
            )
        )

        val newStepsRecords = arrayListOf<StepsRecord>()
        for (record in request.records) {
            // Adjusted both offset values to reflect changes
            val sr = StepsRecord(
                count = record.count,
                startTime = record.startTime,
                startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset,
                endTime = record.endTime,
                endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset,
                metadata = record.metadata
            )
            newStepsRecords.add(sr)
        }

        client.updateRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Esegui l'upsert tramite l'ID record client

Se utilizzi i valori facoltativi ID record client e Versione record client, ti consigliamo di utilizzare insertRecords anziché updateRecords.

La funzione insertRecords consente di aggiornare i dati. Se i dati esistono in Connessione Salute in base all'insieme specificato di ID record client, vengono sovrascritti. In caso contrario, verranno scritti come nuovi dati. Questo scenario è utile ogni volta che devi sincronizzare i dati dal datastore dell'app con Connessione Salute.

L'esempio seguente mostra come eseguire un upsert sui dati estratti dal datastore dell'app:

suspend fun pullStepsFromDatastore() : ArrayList<StepsRecord> {
    val appStepsRecords = arrayListOf<StepsRecord>()
    // Pull data from app datastore
    // ...
    // Make changes to data if necessary
    // ...
    // Store data in appStepsRecords
    // ...
    var sr = StepsRecord(
        // Assign parameters for this record
        metadata = Metadata(
            clientRecordId = cid
        )
    )
    appStepsRecords.add(sr)
    // ...
    return appStepsRecords
}

suspend fun upsertSteps(
    healthConnectClient: HealthConnectClient,
    newStepsRecords: ArrayList<StepsRecord>
) {
    try {
        healthConnectClient.insertRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Successivamente, puoi chiamare queste funzioni nel thread principale.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

Controllo del valore nella versione del record client

Se il processo di upserting dei dati include la versione del record client, Connessione Salute esegue controlli di confronto nei valori di clientRecordVersion. Se la versione dei dati inseriti è superiore a quella dei dati esistenti, si verifica l'upsert. In caso contrario, il processo ignora la modifica e il valore rimane lo stesso.

Per includere il controllo delle versioni nei dati, devi fornire a Metadata.clientRecordVersion un valore Long in base alla tua logica di controllo delle versioni.

val sr = StepsRecord(
    count = count,
    startTime = startTime,
    startZoneOffset = startZoneOffset,
    endTime = endTime,
    endZoneOffset = endZoneOffset,
    metadata = Metadata(
        clientRecordId = cid,
        clientRecordVersion = version
    )
)

Gli upser non incrementano automaticamente version ogni volta che vengono apportate modifiche, impedendo così istanze impreviste di sovrascrittura dei dati. Quindi, devi specificare manualmente un valore più alto.

Best practice

Dopo aver creato la logica, valuta la possibilità di seguire le best practice durante la scrittura o l'aggiornamento dei dati.