Monitorare i passi

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_COUNTER di SensorManager. 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 android in DataOrigin. 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_STEPS in 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_STEPS
  • android.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)
    )
Utilizza 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.") }
    }
}
Poiché gli utenti possono concedere o revocare le autorizzazioni in qualsiasi momento, la tua app deve controllare le autorizzazioni ogni volta prima di utilizzarle e gestire gli scenari in cui l'autorizzazione viene revocata.

Informazioni incluse in un record Passi

Ogni StepsRecord contiene le seguenti informazioni:

  • count: il numero di passi effettuati nell'intervallo di tempo, come Long.
  • 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 */
}