O Conexão Saúde oferece um tipo de dados de passos para registrar contagens de passos usando
o StepsRecord. Os passos são uma medida fundamental no monitoramento de saúde e condicionamento físico.
Ler etapas para dispositivos móveis
Com o Android 14 (nível 34 da API) e a extensão do SDK versão 20 ou mais recente,
a Conexão Saúde oferece contagem de passos no dispositivo. Se algum app tiver recebido a permissão
READ_STEPS, o Conexão Saúde vai começar a capturar passos do
dispositivo Android, e os usuários vão ver os dados de passos adicionados automaticamente às entradas de
Passos do Conexão Saúde.
Para verificar se a contagem de passos no dispositivo está disponível, confira se ele está executando o Android 14 (nível 34 da API) e tem pelo menos a versão 20 da extensão do SDK:
val isStepTrackingAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20
Se o app lê contagens de passos agregadas usando
aggregate e não filtra por DataOrigin, os passos
no dispositivo são incluídos automaticamente no total, e nenhuma mudança é necessária para
a atualização de junho de 2026.
Mudança na atribuição para etapas no dispositivo
A partir da atualização de junho de 2026, as etapas rastreadas nativamente pelo Health
Connect serão atribuídas a um nome de pacote sintético (SPN), como
com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.
Antes, as etapas integradas eram atribuídas ao nome do pacote android.
Os dados históricos de etapas registrados antes de junho de 2026 mantêm o nome do pacote android.
Os SPNs são específicos do dispositivo e têm escopo por aplicativo para proteger a privacidade do usuário:
- Estável:o SPN do dispositivo atual está estável para seu aplicativo.
- Escopo do aplicativo:aplicativos diferentes no mesmo dispositivo veem SPNs diferentes para dados de passos no dispositivo.
Consultar etapas no dispositivo
Como os SPNs são específicos do dispositivo e têm escopo, não codifique valores de SPN. Em vez disso, use a
API getCurrentDeviceDataSource para recuperar
o SPN do dispositivo atual.
Embora a contagem de passos no dispositivo exija a extensão do SDK versão 20 ou mais recente, a API getCurrentDeviceDataSource() está disponível no Android 14 (nível 34 da API) com a extensão do SDK versão 22 ou mais recente. Para usar essa API, defina
compileSdkExtension como 22 ou mais recente no arquivo build.gradle.kts
ou build.gradle no nível do módulo:
Kotlin
android { compileSdk = 35 compileSdkExtension = 22 }
Groovy
android { compileSdk 35 compileSdkExtension 22 }
A API getCurrentDeviceDataSource() ainda não está disponível na biblioteca Jetpack da Conexão Saúde. Os exemplos a seguir usam a API do framework Android,
que exige um Executor e um callback OutcomeReceiver:
import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.OutcomeReceiver
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
healthConnectManager?.getCurrentDeviceDataSource(
context.mainExecutor,
object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
override fun onResult(result: DeviceDataSource) {
val currentDeviceSpn = result.deviceDataOrigin.packageName
}
override fun onError(error: HealthConnectException) {
// Handle error
}
}
)
Se o app precisar ler etapas no dispositivo ou mostrar dados de etapas
divididos por aplicativo ou dispositivo de origem, consulte os registros
em que o DataOrigin é android ou corresponde ao SPN do dispositivo. Se
o app mostrar a atribuição dos dados de passos, use metadata.device
para identificar o dispositivo de origem dos registros individuais. Para etapas no dispositivo
identificadas por um SPN em dados agregados, use metadados do dispositivo, como
model ou manufacturer de DeviceDataSource para atribuição, ou use um
rótulo genérico, como "Seu smartphone", para etapas no dispositivo.
O exemplo a seguir mostra como ler dados agregados de contagem de passos no dispositivo
filtrando por android e o SPN do dispositivo atual:
import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.OutcomeReceiver
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
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine
suspend fun readDeviceStepsByTimeRange(
healthConnectClient: HealthConnectClient,
context: Context,
startTime: Instant,
endTime: Instant
) {
// 1. Check if SDK Extension 22+ is available for getCurrentDeviceDataSource()
val isDataSourceApiAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 22
try {
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
// 2. Safely fetch the package name only if the API is available
val currentDeviceSpn = if (isDataSourceApiAvailable && healthConnectManager != null) {
suspendCancellableCoroutine { continuation ->
healthConnectManager.getCurrentDeviceDataSource(
context.mainExecutor,
object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
override fun onResult(result: DeviceDataSource) {
continuation.resume(result.deviceDataOrigin.packageName)
}
override fun onError(error: HealthConnectException) {
continuation.resumeWithException(error)
}
}
)
}
} 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.
}
}
Contagem de passos no dispositivo
- Uso de sensores: o app Conexão Saúde usa o sensor
TYPE_STEP_COUNTERdoSensorManager. Esse sensor é otimizado para baixo consumo de energia, o que o torna ideal para o rastreamento contínuo de passos em segundo plano. - Granularidade dos dados: para economizar bateria, os dados de passos geralmente são agrupados e gravados no banco de dados da Conexão Saúde no máximo uma vez por minuto.
- Atribuição: as etapas registradas por esse recurso antes de junho de 2026 são
atribuídas ao nome do pacote
androidnoDataOrigin. Depois dessa data, eles são atribuídos a um SPN específico do dispositivo. Consulte Mudança na atribuição para etapas no dispositivo. - Ativação: o mecanismo de contagem de passos no dispositivo só fica ativo quando pelo menos um aplicativo no dispositivo recebe a permissão
READ_STEPSna Conexão Saúde.
Verificar a disponibilidade da Conexão Saúde
Antes de tentar usar o Conexão Saúde, seu app precisa verificar se ele está disponível
no dispositivo do usuário. A Conexão Saúde pode não estar pré-instalada em todos os dispositivos ou pode estar desativada.
É possível verificar a disponibilidade usando o método HealthConnectClient.getSdkStatus().
Como verificar a disponibilidade da Conexão Saúde
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 }
Dependendo do status retornado por getSdkStatus(), você pode orientar o usuário
a instalar ou atualizar o Conexão Saúde na Google Play Store, se necessário.
Permissões necessárias
O acesso às etapas é protegido pelas seguintes permissões:
android.permission.health.READ_STEPSandroid.permission.health.WRITE_STEPS
Para adicionar a capability de etapas ao app, comece solicitando
permissões para o tipo de dados Steps.
Confira a permissão necessária para poder gravar etapas:
<application>
<uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>
Para ler as etapas, solicite as seguintes permissões:
<application>
<uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>
Solicitar permissões do usuário
Depois de criar uma instância de cliente, seu app precisa solicitar permissões aos usuários. Os usuários precisam poder conceder ou negar permissões a qualquer momento. Para isso, crie um conjunto de permissões para os tipos de dados necessários. Verifique se as permissões no conjunto foram declaradas primeiro no manifesto do Android.
val permissions = setOf( HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class) )
getGrantedPermissions
para verificar se o app já tem as permissões necessárias concedidas. Caso contrário, use
createRequestPermissionResultContract
para solicitá-las. Isso mostra a tela de permissões da Conexão Saúde.
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.") } } }
Informações incluídas em um registro de etapas
Cada StepsRecord contém as seguintes informações:
count: o número de etapas realizadas no intervalo de tempo, como umLong.startTime: o horário de início do intervalo de medição.endTime: o horário de término do intervalo de medição.startZoneOffset: o ajuste de horário para o horário de início.endZoneOffset: o ajuste de horário da zona para o horário de término.
Agregações compatíveis
Os seguintes valores agregados estão disponíveis para StepsRecord:
Os seguintes valores agregados estão disponíveis para StepsCadenceRecord:
Exemplo de uso
As seções a seguir mostram como ler e gravar dados do StepsRecord.
Gravar dados de passos
Seu app pode gravar dados de contagem de passos inserindo instâncias de StepsRecord. O exemplo a seguir mostra como registrar 1.000 etapas realizadas por um usuário:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata.autoRecorded( device = Device(type = Device.TYPE_WATCH) ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
Ler dados agregados
A maneira mais comum de ler dados de passos é agregar o total de passos em um período. O exemplo abaixo mostra como ler a contagem total de passos de um usuário em um determinado período:
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 }
Ler dados brutos
O exemplo a seguir mostra como ler dados brutos de StepsRecord entre um horário de início e de término:
val response = healthConnectClient.readRecords( ReadRecordsRequest( StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }