Questa guida illustra il processo di scrittura o aggiornamento dei dati in Connessione Salute.
Configura la struttura dei dati
Prima di scrivere i dati, dobbiamo configurare i record. Per oltre 50 tipi di dati, ognuno ha le proprie strutture. Per ulteriori dettagli sui tipi di dati disponibili, consulta la documentazione di riferimento di Jetpack.
Record di base
Il tipo di dati Passi in Connessione Salute registra il numero di passi effettuati da un utente tra una lettura e l'altra. Il conteggio dei passi è una misurazione comune sulle piattaforme di salute, fitness e benessere.
L'esempio seguente mostra come impostare i dati per il conteggio dei passi:
val stepsRecord = StepsRecord(
count = 120,
startTime = START_TIME,
endTime = END_TIME,
startZoneOffset = START_ZONE_OFFSET,
endZoneOffset = END_ZONE_OFFSET
)
Registrazione con unità di misura
Connessione Salute può archiviare i valori insieme alle relative unità di misura per fornire accuratezza. Un esempio è il tipo di dati Alimentazione, che è vasto e comprensivo. Include un'ampia varietà di campi nutritivi facoltativi, dai carboidrati totali alle vitamine. Ogni punto dati rappresenta le sostanze nutritive che sono state potenzialmente 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 di 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 delle serie. Un esempio è il tipo di dati Battito cardiaco, 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 del battito cardiaco. Ogni campione contiene un valore beatsPerMinute
e un valore time
.
L'esempio seguente mostra come impostare i dati delle serie del battito cardiaco:
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 i conteggi di passaggi per l'inserimento di dati:
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, in particolare quando devi sincronizzare il datastore dell'app con i dati di Connessione Salute, puoi aggiornare i tuoi dati. Esistono due modi per aggiornare i dati esistenti, che dipendono dall'identificatore utilizzato per trovare i record.
Metadati
Consigliamo di esaminare prima il corso Metadata
in quanto è necessario
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 Salute compila automaticamente questo campo quando viene inserito un nuovo record. |
lastModifiedTime
|
Ogni Record tiene traccia anche dell'ultima
modifica del record.Connessione Salute compila automaticamente questo campo. |
clientRecordId
|
A ogni Record può essere associato un ID univoco
da utilizzare come riferimento nel datastore dell'app.
La tua app fornisce questo valore. |
clientRecordVersion
|
Se un record ha clientRecordId , clientRecordVersion può essere utilizzato per consentire ai dati
di rimanere sincronizzati con la versione nel datastore dell'app.La tua app fornisce questo valore. |
Aggiorna tramite Record ID
Per aggiornare i dati, prepara prima i record necessari. Se necessario, apporta eventuali modifiche ai record. Quindi, chiama updateRecords
per
apportare le modifiche.
L'esempio seguente mostra come aggiornare i dati. A questo scopo, ogni record ha i propri valori di offset di zona regolati 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 upsert tramite 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
è in grado di eseguire l'upsert dei dati.
Se i dati esistono in Connessione Salute in base all'insieme specificato di ID record client, vengono sovrascritti. In caso contrario, vengono scritti come nuovi dati.
Questo scenario è utile ogni volta che devi sincronizzare i dati del 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
}
}
Dopodiché, 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 del client, Connessione Salute esegue controlli di confronto nei valori 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 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 upsert non incrementano automaticamente version
ogni volta che vengono apportate modifiche,
impedendo eventuali istanze impreviste di sovrascrittura dei dati. Devi quindi dargli manualmente
un valore più alto.
Best practice per la scrittura dei dati
Le app devono scrivere in Connessione Salute solo dati provenienti dalla tua proprietà.
Se i dati nella tua app sono stati importati da un'altra app, la responsabilità di scrivere i propri dati in Connessione Salute ricade sull'altra app.
Inoltre, è una buona idea implementare una logica che gestisca le eccezioni di scrittura, ad esempio un errore di sistema interno o che i dati sono al di fuori dei limiti. Puoi applicare le strategie di backoff e di ripetizione a un meccanismo di pianificazione dei job. Se scrivere in Connessione Salute alla fine non va a buon fine, assicurati che la tua app possa andare oltre il punto di esportazione. Non dimenticare di registrare e segnalare gli errori per facilitare la diagnosi.
Per il monitoraggio dei dati, puoi seguire un paio di suggerimenti a seconda del modo in cui l'app scrive i dati.
Monitoraggio passivo
Sono incluse le app che eseguono il monitoraggio passivo o della salute, come la registrazione continua dei passi o del battito cardiaco in background.
La tua app deve scrivere periodicamente i dati in Connessione Salute nei seguenti modi:
- A ogni sincronizzazione, scrivi solo i nuovi dati e i dati aggiornati che sono stati modificati dopo l'ultima sincronizzazione.
- Richieste di chunk a un massimo di 1000 record per richiesta di scrittura.
- Utilizza
WorkManager
per pianificare attività periodiche in background, con un periodo di tempo di almeno 15 minuti. Limita l'esecuzione delle attività solo quando il dispositivo è inattivo e non ha la batteria scarica.
val constraints = Constraints.Builder() .requiresBatteryNotLow() .requiresDeviceIdle(true) .build() val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>( 15, TimeUnit.MINUTES, 5, TimeUnit.MINUTES ) .setConstraints(constraints) .build()
Monitoraggio attivo
Sono incluse le app che eseguono il monitoraggio basato su eventi come allenamento e sonno, o input manuali dell'utente come l'alimentazione. Questi record vengono creati quando l'app è in primo piano o in rari eventi in cui viene utilizzata alcune volte al giorno.
Assicurati che l'app non tenga in esecuzione Connessione Salute per l'intera durata dell'evento.
I dati devono essere scritti in Connessione Salute in uno dei due modi seguenti:
- Sincronizza i dati in Connessione Salute al termine dell'evento. Ad esempio, sincronizza i dati quando l'utente termina una sessione di allenamento rilevata.
- Pianifica un'attività una tantum utilizzando
WorkManager
per sincronizzare i dati in un secondo momento.
Best practice per granularità e frequenza delle scritture
Quando scrivi dati in Connessione Salute, usa la risoluzione appropriata. Utilizzare la risoluzione appropriata aiuta a ridurre il carico di archiviazione, mantenendo al contempo dati coerenti e accurati. La risoluzione dei dati include due aspetti:
- Frequenza di scritture: la frequenza con cui l'applicazione invia nuovi dati a Connessione Salute. Ad esempio, scrivi nuovi dati ogni 15 minuti.
- Granularità dei dati scritti: frequenza con cui i dati inviati sono stati campionati. Ad esempio, scrivi campioni del battito cardiaco ogni 5 secondi. Non tutti i tipi di dati richiedono la stessa frequenza di campionamento. L'aggiornamento dei dati sul conteggio dei passi ogni secondo presenta un vantaggio minimo, rispetto a una cadenza meno frequente come ogni 60 secondi. Tuttavia, frequenze di campionamento più elevate possono offrire agli utenti una panoramica più dettagliata e dettagliata dei loro dati su salute e fitness. Le frequenze di campionamento devono trovare un equilibrio tra dettaglio e prestazioni.
Scrivere dati monitorati durante il giorno
Per i dati raccolti regolarmente, come i passaggi, l'applicazione dovrebbe scrivere a Connessione Salute almeno ogni 15 minuti durante il giorno.
Tipo di dati |
Unità |
Prevista |
Esempio |
Passi |
passi |
Ogni minuto |
23:14 - 23:15 - 5 passi 23:16 - 23:17 - 22 passi 23:17 - 23:18 - 8 passi |
Cadenza dei passi |
passi/min |
Ogni minuto |
23:14 - 23:15 - 17:00 23:16 - 23:17 - 22 spm 23:17 - 23:18 - 20:00 |
Spinte in sedia a rotelle |
push |
Ogni minuto |
23:14 - 23:15 - 5 spinte 23:16 - 23:17 - 22 spinte 23:17 - 23:18 - 8 spinte |
Calorie bruciate in fase di attività |
Calorie |
Ogni 15 minuti |
23:15 - 23:30 - 2 Calorie 23:30 - 23:45 - 25 Calorie 23:45 - 00:00 - 5 Calorie |
TotaleCalorieBrute |
Calorie |
Ogni 15 minuti |
23:15 - 23:30 - 16 Calorie 23:30 - 23:45 - 16 Calorie 23:45 - 00:00 - 16 Calorie |
Distanza |
km/min |
Ogni minuto |
23:14-23:15 - 0.008 km 23:16 - 23:16 - 0.021 km 23:17 - 23:18 - 0.012 km |
Dislivello |
M |
Ogni minuto |
20:36 - 20:37 - 3,048 m 20:39 - 20:40 - 3,048 m 23:23 - 23:24 - 9,144 m |
Piani saliti |
piani |
Ogni minuto |
23:14 - 23:15 - 5 piani 23:16 - 23:16 - 22 piani 23:17 - 23:18 - 8 piani |
Battito cardiaco |
bpm |
Ogni minuto |
6:11 - 55 b/m |
Variabilità della frequenza cardiaca (HRmssd) |
ms |
Ogni minuto |
6:11 - 23 ms |
Frequenza respiratoria |
respiri/minuto |
Ogni minuto |
23:14 - 23:15 - 60 respiri/minuto 23:16 - 23:16 - 62 respiri/minuto 23:17 - 23:18 - 64 respiri/minuto |
Saturazione ossigeno |
% |
Ogni ora |
6:11 - 95,208% |
Scrittura delle sessioni
I dati devono essere scritti in Connessione Salute al termine dell'esercizio o della sessione di sonno.
Come best practice, qualsiasi sessione di sonno o allenamento deve essere scritta con il dispositivo di registrazione e i metadati appropriati, tra cui RecordingMethod
.
La tua richiesta deve seguire almeno le indicazioni riportate nella colonna "Prevista" di seguito. Ove possibile, segui le indicazioni "migliori".
Dati rilevati durante un allenamento
Tipo di dati |
Unità |
Prevista |
Cordiali saluti, |
Esempio |
Passi |
passi |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 5 passi 23:16 - 23:17 - 22 passi 23:17 - 23:18 - 8 passi |
Cadenza dei passi |
passi/min |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 35 spm 23:16 - 23:17 - 37 spm 23:17 - 23:18 - 40 spm |
Spinte in sedia a rotelle |
push |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 5 spinte 23:16 - 23:17 - 22 spinte 23:17 - 23:18 - 8 spinte |
CiclismoPedalingCadence |
rpm / respiri al minuto |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 65 giri/min 23:16 - 23:17 - 70 giri/min 23:17 - 23:18 - 68 giri/min |
Potenza |
watt |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 250 watt 23:16 - 23:17 - 255 watt 23:17 - 23:18 - 245 watt |
Velocità |
km/min |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 0.3 km/min 23:16 - 23:17 - 0.4 km/min 23:17 - 23:18 -0,4 km/min |
Distanza |
km/m |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 0.008 km 23:16 - 23:16 - 0.021 km 23:17 - 23:18 - 0.012 km |
Calorie bruciate in fase di attività |
Calorie |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 20 Calorie 23:16 - 23:17 - 20 Calorie 23:17 - 23:18 - 25 Calorie |
TotaleCalorieBrute |
Calorie |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 36 Calorie 23:16 - 23:17 - 36 Calorie 23:17 - 23:18 - 41 Calorie |
Dislivello |
M |
Ogni minuto |
Ogni secondo |
20:36 - 20:37 - 3,048 m 20:39 - 20:40 - 3,048 m 23:23 - 23:24 - 9,144 m |
Percorsi allenamento |
lat/lng/alt |
Ogni 3-5 secondi |
Ogni secondo |
|
Battito cardiaco |
bpm |
Ogni minuto |
Ogni secondo |
23:14-23:15 - 150 b/m 23:16 - 23:17 -152 bpm 23:17 - 23:18 - 155 bpm |
Dati rilevati durante il sonno
Tipo di dati |
Unità |
Campioni previsti |
Esempio |
Preparazione del sonno |
fase |
Periodo di tempo granulare per fase del sonno |
23:46 - 23:50 - sveglio 23:50 - 23:56 - sonno leggero 23:56 - 00:16 - sonno profondo |
Battito cardiaco a riposo |
bpm |
Singolo valore giornaliero (previsto come prima cosa al mattino) |
06:11 - 60 b/m |
Saturazione ossigeno |
% |
Singolo valore giornaliero (previsto come prima cosa al mattino) |
6:11 - 95,208% |