O exemplo abaixo mostra como ler dados brutos do fluxo de trabalho comum.
Ler dados
A Conexão Saúde permite que os apps leiam dados do repositório de dados quando estão em primeiro e segundo plano:
Leituras em primeiro plano: normalmente, é possível ler dados da Conexão Saúde quando o app está em primeiro plano. Nesses casos, considere usar um serviço em primeiro plano para executar essa operação caso o usuário ou o sistema coloque o app em segundo plano durante uma operação de leitura.
Leituras em segundo plano: ao solicitar uma permissão extra do usuário, você pode ler dados depois que o usuário ou o sistema coloca o app em segundo plano. Confira o exemplo completo de leitura em segundo plano.
O tipo de dados "passos" no Conexão Saúde captura o número de passos que um usuário deu entre as leituras. A contagem de passos representa uma medida comum nas plataformas de saúde, condicionamento físico e bem-estar. A Conexão Saúde permite ler e gravar dados de contagem de passos.
Para ler registros, crie uma ReadRecordsRequest e forneça
quando você chamar readRecords.
O exemplo abaixo mostra como ler dados de contagem de passos de um usuário em um determinado período. Para um exemplo estendido com SensorManager,
consulte o guia de dados de contagem de passos.
val response = healthConnectClient.readRecords( ReadRecordsRequest( HeartRateRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }
Também é possível ler os dados de forma agregada usando
aggregate.
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 passos no dispositivo móvel
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, a Conexão Saúde 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 da Conexão Saúde.
Para verificar se a contagem de passos no dispositivo está disponível, verifique se o dispositivo está executando o Android 14 (nível 34 da API) e tem pelo menos a extensão do SDK versão 20:
val isStepTrackingAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20
Se o app ler contagens de passos agregadas usando
aggregate e não filtrar por DataOrigin, os passos no dispositivo
serão incluídos automaticamente no total, e nenhuma mudança será necessária para
a atualização de junho de 2026.
Mudança de atribuição para passos no dispositivo
A partir da atualização de junho de 2026, os passos rastreados nativamente pela Conexão Saúde
serão atribuídos a um nome de pacote sintético (SPN), como
com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.
Anteriormente, os passos integrados eram atribuídos ao nome do pacote android.
Os dados históricos de passos 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ável para o aplicativo.
- Com escopo do aplicativo:aplicativos diferentes no mesmo dispositivo mostram SPNs diferentes para dados de passos no dispositivo.
Consultar passos no dispositivo
Como os SPNs têm escopo e são específicos do dispositivo, 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 11 ou mais recente.
A API getCurrentDeviceDataSource() ainda não está disponível na biblioteca do Jetpack da Conexão Saúde. Os exemplos a seguir usam a API do framework do 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
Se o app precisar ler passos no dispositivo ou mostrar dados de passos detalhados 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 de dados de passos, use metadata.device
para identificar o dispositivo de origem de registros individuais. Para passos no dispositivo identificados por um SPN em dados agregados, é possível usar metadados do dispositivo, como model ou manufacturer de DeviceDataSource para atribuição, ou usar um rótulo genérico, como "Seu smartphone" para passos no dispositivo.
O exemplo a seguir mostra como ler dados agregados de contagem de passos no dispositivo filtrando por android e pelo SPN do dispositivo atual:
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.
}
}
Contagem de passos no dispositivo
- Uso do sensor: a Conexão Saúde usa o sensor
TYPE_STEP_COUNTERdeSensorManager. 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 preservar a duração da bateria, os dados de passos são normalmente agrupados e gravados no banco de dados da Conexão Saúde com uma frequência máxima de uma vez por minuto.
- Atribuição: os passos registrados por esse recurso antes de junho de 2026 são
atribuídos ao nome do pacote
androidnoDataOrigin. Após essa data, eles são atribuídos a um SPN específico do dispositivo. Consulte Mudança de atribuição para passos no dispositivo. - Ativação: o mecanismo de contagem de passos no dispositivo só fica ativo quando pelo menos um aplicativo no dispositivo recebe a
READ_STEPSpermissão na Conexão Saúde.
Exemplo de leitura em segundo plano
Para ler dados em segundo plano, declare a seguinte permissão no arquivo de manifesto:
<application>
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>
O exemplo a seguir mostra como ler dados de contagem de passos em segundo plano para um
usuário em um determinado período usando WorkManager:
class ScheduleWorker(appContext: Context, workerParams: WorkerParameters) : CoroutineWorker(appContext, workerParams) { override suspend fun doWork(): Result { val healthConnectClient = HealthConnectClient.getOrCreate(applicationContext) // Perform background read logic here return Result.success() } }
fun enqueueBackgroundReadWorker(context: Context, healthConnectClient: HealthConnectClient) { if (healthConnectClient .features .getFeatureStatus( HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE ) { val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( "read_health_connect", ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest ) } }
O parâmetro ReadRecordsRequest tem um valor pageSize padrão de 1000.
Se o número de registros em uma única readResponse exceder o pageSize da solicitação, será necessário iterar por todas as páginas da resposta para recuperar todos os registros usando pageToken.
No entanto, tome cuidado para evitar problemas de limitação de taxa.
Exemplo de leitura de pageToken
Recomendamos usar pageToken para ler registros e recuperar todos os dados disponíveis do período solicitado.
O exemplo a seguir mostra como ler todos os registros até que todos os tokens de página tenham sido esgotados:
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 }
Ler dados gravados anteriormente
Se um app tiver gravado registros na Conexão Saúde antes, ele poderá ler dados históricos. Isso se aplica a cenários em que o app precisa ser sincronizado novamente com a Conexão Saúde depois que o usuário o reinstala.
Algumas restrições de leitura se aplicam:
Para o Android 14 e versões mais recentes
- Não há limite histórico para um app ler os próprios dados.
- Limite de 30 dias para um app ler outros dados.
Para o Android 13 e versões anteriores
- Limite de 30 dias para o app ler qualquer dado.
As restrições podem ser removidas solicitando uma permissão de leitura.
Para ler dados históricos, é necessário indicar o nome do pacote como um
DataOrigin objeto no parâmetro dataOriginFilter do seu
ReadRecordsRequest.
O exemplo a seguir mostra como indicar o nome de um pacote ao ler os registros de frequência cardíaca:
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 }
Ler dados com mais de 30 dias
Por padrão, todos os aplicativos podem ler dados da Conexão Saúde registrados até 30 dias antes da permissão ser concedida.
Se você precisar estender as permissões de leitura além de qualquer uma das
restrições padrão, solicite o
PERMISSION_READ_HEALTH_DATA_HISTORY.
Caso contrário, sem essa permissão, uma tentativa de ler registros com mais de 30 dias resulta em um erro.
Histórico de permissões de um app excluído
Se um usuário excluir seu app, todas as permissões, incluindo a permissão de histórico, serão revogadas. Se o usuário reinstalar o app e conceder a permissão novamente, as mesmas restrições padrão serão aplicadas, e o app poderá ler dados da Conexão Saúde registrados até 30 dias antes dessa nova data.
Por exemplo, suponha que o usuário exclua seu app em 10 de maio de 2023 e reinstale o app em 15 de maio de 2023, concedendo permissões de leitura. A data mais antiga de que o app poderá ler dados por padrão será 15 de abril de 2023.
Tratar exceções
A plataforma Conexão Saúde gera exceções padrão para operações CRUD quando um problema é encontrado. O app precisa capturar e processar cada uma dessas exceções conforme adequado.
Cada método no HealthConnectClient lista as exceções que podem ser geradas.
Em geral, o app precisa lidar com as seguintes exceções:
| Exceção | Descrição | Prática recomendada |
|---|---|---|
IllegalStateException
| Ocorreu um dos seguintes cenários:
| Gerencie possíveis problemas com as entradas antes de fazer uma solicitação. De preferência, atribua valores a variáveis ou use elas como parâmetros em uma função personalizada em vez de usá-las diretamente nas solicitações para aplicar estratégias de tratamento de erros. |
IOException
| Ocorreram problemas ao ler e gravar dados do disco. | Para evitar esse problema, confira algumas sugestões:
|
RemoteException
| Ocorreram erros na comunicação com o serviço subjacente ao qual o SDK se conecta. Por exemplo, seu app está tentando excluir um registro com um determinado uid. No entanto, a exceção
é gerada após o app descobrir, ao verificar no serviço subjacente, que
o registro não existe.
| Para evitar esse problema, confira algumas sugestões:
|
SecurityException
| Há problemas encontrados quando as solicitações exigem permissões que não são concedidas. | Para evitar isso, verifique se você declarou o uso de tipos de dados da Conexão Saúde para o app publicado. Além disso, é necessário declarar as permissões da Conexão Saúde no arquivo de manifesto e na sua atividade. |