Cómo registrar tus pasos

Health Connect proporciona un tipo de datos steps para registrar recuentos de pasos con StepsRecord. Los pasos son una medición fundamental en el seguimiento de la salud y la actividad física.

Cómo leer pasos móviles

Con Android 14 (nivel de API 34) y la extensión del SDK versión 20 o posterior, Health Connect proporciona el recuento de pasos integrado en el dispositivo. Si alguna app recibió el permiso READ_STEPS, Health Connect comienza a capturar pasos desde el dispositivo con tecnología Android, y los usuarios ven los datos de pasos agregados automáticamente a las entradas de Pasos de Health Connect.

Para verificar si el recuento de pasos integrado en el dispositivo está disponible, verifica que el dispositivo ejecute Android 14 (nivel de API 34) y tenga al menos la extensión del SDK versión 20:

val isStepTrackingAvailable =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20

Si tu app lee recuentos de pasos agregados con aggregate y no filtra por DataOrigin, los pasos integrados en el dispositivo se incluyen automáticamente en el total, y no se requieren cambios para la actualización de junio de 2026.

Cambio de atribución para pasos integrado en el dispositivo

A partir de la actualización de junio de 2026, los pasos que Health Connect rastrea de forma nativa se atribuyen a un nombre de paquete sintético (SPN), como com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.

Anteriormente, los pasos integrados se atribuían al nombre del paquete android. Los datos históricos de pasos registrados antes de junio de 2026 conservan el nombre del paquete android.

Los SPN son específicos del dispositivo y se limitan por aplicación para proteger la privacidad del usuario:

  • Estable: El SPN del dispositivo actual es estable para tu aplicación.
  • Alcance de la aplicación: Las diferentes aplicaciones en el mismo dispositivo ven diferentes SPN para los datos de pasos integrados en el dispositivo.

Consulta de pasos integrado en el dispositivo

Debido a que los SPN tienen un alcance limitado y son específicos del dispositivo, no debes codificar de forma rígida los valores de SPN. En su lugar, usa la API de getCurrentDeviceDataSource() para recuperar el SPN del dispositivo actual.

Si bien el recuento de pasos integrado en el dispositivo requiere la extensión del SDK versión 20 o posterior, la API de getCurrentDeviceDataSource() está disponible en Android 14 (nivel de API 34) con la extensión del SDK versión 11 o posterior.

La API de getCurrentDeviceDataSource() aún no está disponible en la biblioteca de Health Connect Jetpack. En su lugar, los siguientes ejemplos usan la API del framework de Android:

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

Si tu app necesita leer pasos integrados en el dispositivo o si muestra datos de pasos desglosados por aplicación o dispositivo de origen, debes consultar los registros en los que DataOrigin es android o coincide con el SPN del dispositivo. Si tu app muestra la atribución de los datos de pasos, usa metadata.device para identificar el dispositivo de origen de los registros individuales. Para los pasos integrados en el dispositivo identificados por un SPN en datos agregados, puedes usar metadatos del dispositivo, como model o manufacturer de DeviceDataSource para la atribución, o usar una etiqueta genérica como "Tu teléfono" para los pasos integrados en el dispositivo.

En el siguiente ejemplo, se muestra cómo leer datos agregados de recuento de pasos en el dispositivo filtrando por android y el SPN del dispositivo actual:

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.
    }
}

Recuento de pasos en el dispositivo

  • Uso del sensor: Health Connect utiliza el TYPE_STEP_COUNTER sensor de SensorManager. Este sensor está optimizado para un bajo consumo de energía, lo que lo hace ideal para el seguimiento continuo de pasos en segundo plano.
  • Granularidad de los datos: Para conservar la duración de la batería, los datos de pasos suelen agruparse y escribirse en la base de datos de Health Connect con una frecuencia no superior a una vez por minuto.
  • Atribución: Los pasos registrados por esta función antes de junio de 2026 se atribuyen al nombre del paquete android en DataOrigin. Después de esta fecha, se atribuyen a un SPN específico del dispositivo. Consulta Cambio de atribución para pasos integrado en el dispositivo.
  • Activación: El mecanismo de recuento de pasos integrado en el dispositivo solo está activo cuando al menos una aplicación del dispositivo recibió el READ_STEPS permiso en Health Connect.

Verifica la disponibilidad de Health Connect

Antes de intentar usar Health Connect, tu app debe verificar que esté disponible en el dispositivo del usuario. Es posible que Health Connect no esté preinstalado en todos los dispositivos o que esté inhabilitado. Puedes verificar la disponibilidad con el método HealthConnectClient.getSdkStatus().

Cómo verificar la disponibilidad de 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
}

Según el estado que muestra getSdkStatus(), puedes guiar al usuario para que instale o actualice Health Connect desde Google Play Store si es necesario.

Permisos necesarios

El acceso a los pasos está protegido por los siguientes permisos:

  • android.permission.health.READ_STEPS
  • android.permission.health.WRITE_STEPS

Si deseas agregar la función de pasos a tu app, comienza por solicitar permisos para el tipo de datos Steps.

Este es el permiso que debes declarar para poder escribir pasos:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>

Para leer pasos, debes solicitar los siguientes permisos:

<application>
  <uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>

Solicita permisos al usuario

Después de crear una instancia de cliente, tu app debe solicitarle permisos al usuario. Los usuarios deben poder otorgar o rechazar permisos en cualquier momento. Para hacerlo, crea un conjunto de permisos para los tipos de datos necesarios. Primero, asegúrate de que los permisos del conjunto se declaren en tu manifiesto de Android.

val permissions =
    setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class)
    )
Usa getGrantedPermissions para ver si tu app ya tiene otorgados los permisos necesarios. De lo contrario, usa createRequestPermissionResultContract para solicitar esos permisos. Se mostrará la pantalla de permisos de Health Connect.
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.") }
    }
}
Debido a que los usuarios pueden otorgar o revocar permisos en cualquier momento, tu app debe verificar los permisos cada vez antes de usarlos y controlar las situaciones en las que se pierde el permiso.

Información que se incluye en un registro de pasos

Cada StepsRecord contiene la siguiente información:

  • count: Es la cantidad de pasos realizados en el intervalo de tiempo, como un Long.
  • startTime: Es la hora de inicio del intervalo de medición.
  • endTime: Es la hora de finalización del intervalo de medición.
  • startZoneOffset: Es la compensación de zona para la hora de inicio.
  • endZoneOffset: Es la compensación de zona para la hora de finalización.

Agregaciones admitidas

Los siguientes valores agregados están disponibles para StepsRecord:

Los siguientes valores agregados están disponibles para StepsCadenceRecord:

Ejemplo de uso

En las siguientes secciones, se muestra cómo leer y escribir datos de StepsRecord.

Escribe datos de pasos

Tu app puede escribir datos de recuento de pasos insertando StepsRecord instancias. En el siguiente ejemplo, se muestra cómo registrar 1,000 pasos realizados por un usuario:

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))

Cómo leer datos agregados

La forma más común de leer datos de pasos es agregar el total de pasos durante un período. En el siguiente ejemplo, se muestra cómo leer el recuento total de pasos para un usuario en un período determinado:

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
}

Cómo leer datos sin procesar

En el siguiente ejemplo, se muestra cómo leer datos sin procesar de StepsRecord datos entre una hora de inicio y una de finalización:

val response = healthConnectClient.readRecords(
    ReadRecordsRequest(
        StepsRecord::class,
        timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
    )
)
response.records.forEach { record ->
    /* Process records */
}