A API Recording em dispositivos móveis permite que seu app grave dados de condicionamento físico de um dispositivo móvel de maneira eficiente em termos de bateria. Por exemplo, use essa API para registrar etapas, semelhante a um podômetro que recupera dados de contagem de passos. Essa API não exige conta, ou seja, não é necessário ter uma Conta do Google para usar o serviço, e os dados são armazenados no dispositivo.
Este guia mostra como usar a API Recording em dispositivos móveis nas suas experiências de saúde e fitness.
Consulte o exemplo da API Recording em dispositivos móveis no GitHub.
Detalhes importantes
Há vários recursos notáveis exclusivos da API Recording em dispositivos móveis:
- Quando a assinatura de gravação começa ou é renovada, os dados desde a última assinatura (por até 10 dias) ficam acessíveis.
- Os dados só ficam disponíveis quando há uma assinatura ativa. Se uma assinatura
for removida chamando
unsubscribe
, os dados coletados não poderão ser acessados.
Tipos de dados
A API Recording em dispositivos móveis pode gravar os seguintes tipos de dados:
Primeiros passos
Para começar, adicione a seguinte dependência ao arquivo build.gradle
:
DSL do Kotlin
plugin {
id("com.android.application")
}
...
dependencies {
implementation("com.google.android.gms:play-services-fitness:21.2.0")
}
DSL do Groovy
apply plugin: 'com.android.application'
...
dependencies {
implementation 'com.google.android.gms:play-services-fitness:21.2.0'
}
Solicitar permissões
Para gravar dados usando a API Recording em dispositivos móveis, seu app precisa solicitar a seguinte permissão:
android.permission.ACTIVITY_RECOGNITION
Realizar uma verificação da versão do Play Services
Para usar a API Recording em dispositivos móveis, o usuário precisa ter o Google Play Services
atualizado para LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE
. Para verificar isso, use o método isGooglePlayServicesAvailable
:
val hasMinPlayServices = isGooglePlayServicesAvailable(context, LocalRecordingClient.LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE)
if(hasMinPlayServices != ConnectionResult.SUCCESS) {
// Prompt user to update their device's Google Play services app and return
}
// Continue with Recording API functions
Caso contrário, se a versão do Google Play Services do usuário for muito baixa, o sistema
vai gerar uma exceção ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED
.
Inscrever-se nos dados do Fitness
Para solicitar a coleta em segundo plano de dados de passos, use o método
subscribe
, conforme mostrado no snippet de código a seguir:
val localRecordingClient = FitnessLocal.getLocalRecordingClient(this)
// Subscribe to steps data
localRecordingClient.subscribe(LocalDataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener {
Log.i(TAG, "Successfully subscribed!")
}
.addOnFailureListener { e ->
Log.w(TAG, "There was a problem subscribing.", e)
}
Ler e processar dados de condicionamento físico
Depois de se inscrever, solicite os dados usando o método readData
. Em seguida, você pode
extrair LocalDataPoints do LocalDataSet
resultante
fazendo um LocalDataReadRequest
, conforme mostrado no snippet de código
a seguir:
val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusWeeks(1)
val readRequest =
LocalDataReadRequest.Builder()
// The data request can specify multiple data types to return,
// effectively combining multiple data queries into one call.
// This example demonstrates aggregating only one data type.
.aggregate(LocalDataType.TYPE_STEP_COUNT_DELTA)
// Analogous to a "Group By" in SQL, defines how data should be
// aggregated. bucketByTime allows bucketing by time span.
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
.build()
localRecordingClient.readData(readRequest).addOnSuccessListener { response ->
// The aggregate query puts datasets into buckets, so flatten into a
// single list of datasets.
for (dataSet in response.buckets.flatMap { it.dataSets }) {
dumpDataSet(dataSet)
}
}
.addOnFailureListener { e ->
Log.w(TAG,"There was an error reading data", e)
}
fun dumpDataSet(dataSet: LocalDataSet) {
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name}")
for (dp in dataSet.dataPoints) {
Log.i(TAG,"Data point:")
Log.i(TAG,"\tType: ${dp.dataType.name}")
Log.i(TAG,"\tStart: ${dp.getStartTime(TimeUnit.HOURS)}")
Log.i(TAG,"\tEnd: ${dp.getEndTime(TimeUnit.HOURS)}")
for (field in dp.dataType.fields) {
Log.i(TAG,"\tLocalField: ${field.name.toString()} LocalValue: ${dp.getValue(field)}")
}
}
}
O LocalRecordingClient
atualiza continuamente a coleta de dados. Você pode
usar readData
para extrair os números mais recentes a qualquer momento.
O LocalRecordingClient
armazena dados de até 10 dias. Para reduzir o risco de perda de dados, use o WorkManager para coletar dados periodicamente em segundo plano.
Cancelar a inscrição nos dados de condicionamento físico
Para liberar recursos, cancele a inscrição na
coleta de dados do sensor quando o app não precisar mais deles. Para
cancelar a inscrição, use o método unsubscribe
:
val localRecordingClient = FitnessLocal.getLocalRecordingClient(this)
// Unsubscribe from steps data
localRecordingClient.unsubscribe(LocalDataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener {
Log.i(TAG, "Successfully unsubscribed!")
}
.addOnFailureListener { e ->
Log.w(TAG, "There was a problem unsubscribing.", e)
}