API записи на мобильном телефоне

API записи на мобильном телефоне позволяет вашему приложению регистрировать шаги с мобильного устройства экономичным образом. Этот API без учета учета, что означает, что он не требует учетной записи Google для использования Сервиса, а данные хранятся на устройстве.

Это руководство показывает вам, как использовать API записи на мобильном телефоне в вашем опыте здоровья и фитнеса.

Примечательные детали

There are several notable features unique to the Recording API on mobile:

  • Once the recording subscription starts or is renewed, data since the latest subscription - for up to 10 days - is accessible.
  • Data is only available when there is an active subscription. If a subscription is removed by calling unsubscribe , collected step data won't be accessible.

Типы данных

The Recording API on mobile can record the following data types:

Начать

To get started, add the following dependency in your build.gradle file:

Котлин DSL

plugin {
  id("com.android.application")
}

...

dependencies {
  implementation("com.google.android.gms:play-services-fitness:21.2.0")
}

Отличный DSL

apply plugin: 'com.android.application'

...

dependencies {
  implementation 'com.google.android.gms:play-services-fitness:21.2.0'
}

Запросить разрешения

To record data using the Recording API on mobile, your app will need to request the following permission :

  • android.permission.ACTIVITY_RECOGNITION

Выполните проверку версии Play Services

To use the Recording API on mobile, the user must have Google Play services updated to LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE . You can check for this using the isGooglePlayServicesAvailable method:

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

В противном случае, если версия сервисов Google Play пользователя слишком низкая, система выдает исключение ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED .

Подписаться на фитнес-данные

To request background collection of steps data, use the subscribe method, as shown in the following code snippet:

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

Чтение и обработка данных о фитнесе

Once subscribed, request the data using the readData method. Then, you can obtain LocalDataPoints from the resulting LocalDataSet by making a LocalDataReadRequest , as shown in the following code snippet:

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

The LocalRecordingClient continuously updates its collection of data. You can use readData to pull the latest numbers at any time.

Note that the LocalRecordingClient stores up to 10 days of data. To reduce the risk of losing data, you can use WorkManager to periodically collect the data in the background.

Отписаться от фитнес-данных

In order to free up resources, you should make sure to unsubscribe from the collection of sensor data when your app is no longer in need of it. Чтобы отписаться, используйте метод 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)
  }