Health Connect fornisce un tipo di dati passi per registrare i numeri di passi utilizzando
StepsRecord. I passi sono una misurazione fondamentale nel monitoraggio della salute
e del fitness.
Lettura dei passi da dispositivo mobile
Con Android 14 (livello API 34) e la versione 20 o successive dell'estensione SDK,
Connessione Salute fornisce il conteggio dei passi sul dispositivo. Se a un'app è stata concessa
l'autorizzazione READ_STEPS, Connessione Salute inizia a registrare i passi dal
dispositivo Android e gli utenti vedono i dati sui passi aggiunti automaticamente alle
voci Passi di Connessione Salute.
Per verificare se il conteggio dei passi sul dispositivo è disponibile, controlla che il dispositivo utilizzi Android 14 (livello API 34) e abbia almeno la versione 20 dell'estensione SDK:
val isStepTrackingAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20
Se la tua app legge i conteggi dei passi aggregati utilizzando
aggregate e non filtra in base a DataOrigin, i passi sul dispositivo
vengono inclusi automaticamente nel totale e non sono necessarie modifiche per
l'aggiornamento di giugno 2026.
Modifica dell'attribuzione per i passi sul dispositivo
A partire dall'aggiornamento di giugno 2026, i passi monitorati in modo nativo da Connessione
Salute vengono attribuiti a un nome pacchetto sintetico (SPN), ad esempio
com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.
In precedenza, i passi integrati venivano attribuiti al nome del pacchetto android.
I dati storici sui passi registrati prima di giugno 2026 conservano il nome del pacchetto android.
I nomi principali del servizio sono specifici per dispositivo e vengono definiti in base all'applicazione per proteggere la privacy degli utenti:
- Stabile:l'SPN per il dispositivo attuale è stabile per la tua applicazione.
- Ambito dell'applicazione:diverse applicazioni sullo stesso dispositivo visualizzano SPN diversi per i dati dei passi sul dispositivo.
Query per i passi sul dispositivo
Poiché gli SPN sono specifici per il dispositivo e hanno un ambito limitato, non devi codificare i valori SPN. Utilizza invece l'API getCurrentDeviceDataSource() per recuperare l'SPN per il dispositivo corrente.
Sebbene il conteggio dei passi sul dispositivo richieda la versione 20 o successive dell'estensione SDK,
l'API getCurrentDeviceDataSource() è disponibile su Android 14 (livello API
34) con la versione 11 o successive dell'estensione SDK.
L'API getCurrentDeviceDataSource() non è ancora disponibile nella libreria Jetpack di Health
Connect. Gli esempi seguenti utilizzano invece l'API Android Framework:
import android.content.Context
import android.health.connect.HealthConnectManager
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
val deviceDataSource = healthConnectManager?.getCurrentDeviceDataSource()
val currentDeviceSpn = deviceDataSource?.deviceDataOrigin?.packageName
Se la tua app deve leggere i passi sul dispositivo o se mostra i dati dei passi suddivisi per applicazione o dispositivo di origine, devi eseguire query per i record in cui DataOrigin è android o corrisponde all'SPN del dispositivo. Se la tua app mostra l'attribuzione dei dati dei passi, utilizza metadata.device per identificare il dispositivo di origine per i singoli record. Per i passi sul dispositivo identificati da un SPN nei dati aggregati, puoi utilizzare i metadati del dispositivo, ad esempio model o manufacturer da DeviceDataSource per l'attribuzione, oppure utilizzare un'etichetta generica come "Il tuo smartphone" per i passi sul dispositivo.
Il seguente esempio mostra come leggere i dati aggregati del conteggio dei passi sul dispositivo
filtrando sia android sia l'SPN del dispositivo corrente:
import android.content.Context
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant
suspend fun readDeviceStepsByTimeRange(
healthConnectClient: HealthConnectClient,
context: Context,
startTime: Instant,
endTime: Instant
) {
// 1. Check if SDK Extension 11+ is available for getCurrentDeviceDataSource()
val isDataSourceApiAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.U &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.U) >= 11
try {
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
// 2. Safely fetch the package name only if API is available and data exists
val currentDeviceSpn = if (isDataSourceApiAvailable) {
healthConnectManager?.getCurrentDeviceDataSource()?.deviceDataOrigin?.packageName
} else {
null
}
val dataOriginFilters = mutableSetOf(DataOrigin("android"))
// 3. Explicit null-safety check using .let
currentDeviceSpn?.let {
dataOriginFilters.add(DataOrigin(it))
}
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = dataOriginFilters
)
)
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Now this catch block only handles actual runtime exceptions,
// rather than Errors from missing methods.
}
}
Conteggio dei passi on-device
- Utilizzo dei sensori: Health Connect utilizza il sensore
TYPE_STEP_COUNTERdiSensorManager. Questo sensore è ottimizzato per un basso consumo energetico, il che lo rende ideale per il monitoraggio continuo dei passi in background. - Granularità dei dati: per preservare la durata della batteria, i dati sui passi vengono in genere raggruppati e scritti nel database di Connessione Salute non più di una volta al minuto.
- Attribuzione: i passi registrati da questa funzionalità prima di giugno 2026 vengono
attribuiti al nome del pacchetto
androidinDataOrigin. Dopo questa data, vengono attribuiti a un SPN specifico del dispositivo. Vedi Modifica dell'attribuzione per i passi sul dispositivo. - Attivazione: il meccanismo di conteggio dei passi sul dispositivo è attivo solo quando ad almeno un'applicazione sul dispositivo è stata concessa l'autorizzazione
READ_STEPSin Health Connect.
Controlla la disponibilità di Connessione Salute
Prima di tentare di utilizzare Health Connect, la tua app deve verificare che Health Connect sia disponibile sul dispositivo dell'utente. Health Connect potrebbe non essere preinstallato su tutti i dispositivi o potrebbe essere disattivato.
Puoi verificare la disponibilità utilizzando il metodo HealthConnectClient.getSdkStatus().
Come verificare la disponibilità di Health Connect
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName) if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) { // Health Connect is not available. Guide the user to install/enable it. // For example, show a dialog. return // early return as there is no viable integration } if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) { // Health Connect is available but requires an update. // Optionally redirect to package installer to find a provider, for example: val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding" context.startActivity( Intent(Intent.ACTION_VIEW).apply { setPackage("com.android.vending") data = Uri.parse(uriString) putExtra("overlay", true) putExtra("callerId", context.packageName) } ) return } // Health Connect is available, obtain a HealthConnectClient instance val healthConnectClient = HealthConnectClient.getOrCreate(context) // Issue operations with healthConnectClient }
A seconda dello stato restituito da getSdkStatus(), puoi guidare l'utente
all'installazione o all'aggiornamento di Connessione Salute dal Google Play Store, se necessario.
Autorizzazioni obbligatorie
L'accesso ai passi è protetto dalle seguenti autorizzazioni:
android.permission.health.READ_STEPSandroid.permission.health.WRITE_STEPS
Per aggiungere la funzionalità di passi alla tua app, inizia richiedendo
le autorizzazioni per il tipo di dati Steps.
Ecco l'autorizzazione che devi dichiarare per poter scrivere i passi:
<application>
<uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>
Per leggere i passi, devi richiedere le seguenti autorizzazioni:
<application>
<uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>
Richiedi le autorizzazioni all'utente
Dopo aver creato un'istanza client, la tua app deve richiedere le autorizzazioni all'utente. Gli utenti devono poter concedere o negare le autorizzazioni in qualsiasi momento. A questo scopo, crea un set di autorizzazioni per i tipi di dati richiesti. Assicurati che le autorizzazioni nel set siano dichiarate prima nel manifest di Android.
val permissions = setOf( HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class) )
getGrantedPermissions
per verificare se la tua app dispone già delle autorizzazioni richieste. In caso contrario, utilizza
createRequestPermissionResultContract
per richiedere queste autorizzazioni. Viene visualizzata la schermata delle autorizzazioni di Connessione Salute.
val permissions = setOf( HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class), HealthPermission.getReadPermission(HeartRateRecord::class), HealthPermission.getWritePermission(HeartRateRecord::class) ) val requestPermissionsLauncher = rememberLauncherForActivityResult( contract = PermissionController.createRequestPermissionResultContract() ) { grantedPermissions -> if (grantedPermissions.containsAll(permissions)) { coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") } } else { coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") } } }
Informazioni incluse in un record Passi
Ogni StepsRecord contiene le seguenti informazioni:
count: il numero di passi effettuati nell'intervallo di tempo, comeLong.startTime: l'ora di inizio dell'intervallo di misurazione.endTime: l'ora di fine dell'intervallo di misurazione.startZoneOffset: l'offset della zona per l'ora di inizio.endZoneOffset: l'offset della zona per l'ora di fine.
Aggregazioni supportate
Per StepsRecord sono disponibili i seguenti valori aggregati:
Per StepsCadenceRecord sono disponibili i seguenti valori aggregati:
Esempio di utilizzo
Le sezioni seguenti mostrano come leggere e scrivere i dati StepsRecord.
Scrittura dei dati sui passi
La tua app può scrivere i dati del conteggio dei passi inserendo istanze di StepsRecord. L'esempio seguente mostra come registrare 1000 passi effettuati da un utente:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
Lettura dei dati aggregati
Il modo più comune per leggere i dati sui passi è aggregare il totale dei passi in un periodo di tempo. Il seguente esempio mostra come leggere il conteggio totale dei passi per un utente in un determinato intervallo di tempo:
suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long { val response = healthConnectClient.aggregate( AggregateRequest( metrics = setOf(StepsRecord.COUNT_TOTAL), timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) return response[StepsRecord.COUNT_TOTAL] ?: 0L }
Lettura dei dati non elaborati
Il seguente esempio mostra come leggere i dati StepsRecord grezzi
tra un'ora di inizio e di fine:
val response = healthConnectClient.readRecords( ReadRecordsRequest( StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }