L'esempio seguente mostra come leggere i dati non elaborati nell'ambito del flusso di lavoro comune.
Lettura di dati
Connessione Salute consente alle app di leggere i dati dall'archivio dati quando l'app è in primo piano e in background:
Letture in primo piano: in genere puoi leggere i dati da Connessione Salute quando la tua app è in primo piano. In questi casi, puoi prendere in considerazione l'utilizzo di un servizio in primo piano per eseguire questa operazione nel caso in cui l'utente o il sistema metta la tua app in background durante un'operazione di lettura.
Letture in background: se richiedi un'autorizzazione aggiuntiva all'utente, puoi leggere i dati dopo che l'utente o il sistema mette la tua app in background. Vedi l'esempio completo di lettura in background.
Il tipo di dati Passi in Connessione Salute acquisisce il numero di passi che un utente ha compiuto tra le letture. Il conteggio dei passi rappresenta una misurazione comune su piattaforme per la salute, il fitness e il benessere. Connessione Salute semplifica la lettura e la scrittura dei dati sul conteggio dei passi.
Per leggere i record, crea un ReadRecordsRequest
e forniscilo quando chiami readRecords
.
L'esempio seguente mostra come leggere i dati del conteggio dei passi per un utente in un determinato periodo di tempo. Per un esempio esteso con SensorManager
,
consulta la guida ai dati del conteggio dei passi.
suspend fun readHeartRateByTimeRange(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (record in response.records) {
// Process each record
}
} catch (e: Exception) {
// Run error handling here
}
}
Puoi anche leggere i tuoi dati in modo aggregato utilizzando
aggregate
.
suspend fun readStepsByTimeRange(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
// The result may be null if no data is available in the time range
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Run error handling here
}
}
Esempio di lettura in background
Per leggere i dati in background, dichiara la seguente autorizzazione nel file manifest:
<application>
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>
Il seguente esempio mostra come leggere i dati del conteggio dei passi in background per un utente in un determinato periodo di tempo utilizzando WorkManager
:
class ScheduleWorker(private val appContext: Context, workerParams: WorkerParameters):
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
// Read data and process it.
...
// Return success indicating successful data retrieval
return Result.success()
}
}
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Check if necessary permission is granted
val grantedPermissions = healthConnectClient.permissionController.getGrantedPermissions()
if (PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND !in grantedPermissions) {
// Perform read in foreground
...
} else {
// Schedule the periodic work request in background
val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"read_health_connect",
ExistingPeriodicWorkPolicy.KEEP,
periodicWorkRequest
)
}
} else {
// Background reading is not available, perform read in foreground
...
}
Il parametro ReadRecordsRequest
ha un valore predefinito pageSize
di 1000.
Se il numero di record in un singolo readResponse
supera il
pageSize
della richiesta, devi scorrere
tutte le pagine della risposta per recuperare tutti i record utilizzando pageToken
.
Tuttavia, fai attenzione a evitare problemi di limitazione della frequenza.
Esempio di lettura di pageToken
Ti consigliamo di utilizzare pageToken
per leggere i record e recuperare tutti i dati disponibili del periodo di tempo richiesto.
L'esempio seguente mostra come leggere tutti i record finché tutti i token di pagina non sono stati esauriti:
val type = HeartRateRecord::class
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofDays(7))
try {
var pageToken: String? = null
do {
val readResponse =
healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = type,
timeRangeFilter = TimeRangeFilter.between(
startTime,
endTime
),
pageToken = pageToken
)
)
val records = readResponse.records
// Do something with records
pageToken = readResponse.pageToken
} while (pageToken != null)
} catch (quotaError: IllegalStateException) {
// Backoff
}
Per informazioni sulle best practice per la lettura di set di dati di grandi dimensioni, consulta Pianificare di evitare la limitazione della frequenza.
Leggere i dati scritti in precedenza
Se un'app ha scritto record in Connessione Salute in precedenza, è possibile che l'app legga i dati storici. Ciò è applicabile agli scenari in cui l'app deve essere risincronizzata con Connessione Salute dopo che l'utente l'ha reinstallata.
Si applicano alcune limitazioni di lettura:
Per Android 14 e versioni successive
- Nessun limite storico alla lettura dei propri dati da parte di un'app.
- Limite di 30 giorni per la lettura di altri dati da parte di un'app.
Per Android 13 e versioni precedenti
- Limite di 30 giorni per la lettura di qualsiasi dato da parte dell'app.
Le limitazioni possono essere rimosse richiedendo un'autorizzazione di lettura.
Per leggere i dati storici, devi indicare il nome del pacchetto come oggetto
DataOrigin
nel parametro dataOriginFilter
del tuo
ReadRecordsRequest
.
L'esempio seguente mostra come indicare un nome del pacchetto durante la lettura dei record della frequenza cardiaca:
try {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = setOf(DataOrigin("com.my.package.name"))
)
)
for (record in response.records) {
// Process each record
}
} catch (e: Exception) {
// Run error handling here
}
Leggi i dati più vecchi di 30 giorni
Per impostazione predefinita, tutte le applicazioni possono leggere i dati di 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.