Fitnessdaten mit der Recording API aufzeichnen

Mit der Recording API auf Mobilgeräten kann Ihre App Fitnessdaten von einem Mobilgerät auf akkusparende Weise aufzeichnen. Mit dieser API können Sie beispielsweise Schritte aufzeichnen, ähnlich wie ein Schrittzähler Schrittzählerdaten abruft. Für diese API ist kein Konto erforderlich. Das bedeutet, dass für die Nutzung des Dienstes kein Google-Konto erforderlich ist und Daten auf dem Gerät gespeichert werden.

In dieser Anleitung erfahren Sie, wie Sie die Recording API in Ihren Gesundheits- und Fitness-Apps auf Mobilgeräten verwenden.

Ein Beispiel finden Sie im Recording API on mobile sample auf GitHub.

Wichtige Details

Es gibt einige wichtige Funktionen, die nur in der Recording API auf Mobilgeräten verfügbar sind:

  • Sobald das Aufzeichnungsabo beginnt oder verlängert wird, sind Daten seit dem letzten Abo für bis zu 10 Tage zugänglich.
  • Daten sind nur verfügbar, wenn ein aktives Abo vorhanden ist. Wenn ein Abo durch Aufrufen von unsubscribe entfernt wird, sind die erhobenen Daten nicht mehr zugänglich.

Datentypen

Mit der Recording API auf dem Mobilgerät können die folgenden Datentypen aufgezeichnet werden:

Jetzt starten

Fügen Sie dazu der Datei build.gradle die folgende Abhängigkeit hinzu:

Kotlin DSL

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

...

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

Groovy-DSL

apply plugin: 'com.android.application'

...

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

Berechtigungen anfordern

Wenn Sie Daten mit der Recording API auf Mobilgeräten aufzeichnen möchten, muss Ihre App die folgende Berechtigung anfordern:

  • android.permission.ACTIVITY_RECOGNITION

Version der Play-Dienste prüfen

Wenn Sie die Recording API auf Mobilgeräten verwenden möchten, müssen die Google Play-Dienste auf LOCAL_RECORDING_CLIENT_MIN_VERSION_CODE aktualisiert sein. Sie können dies mit der Methode isGooglePlayServicesAvailable prüfen:

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

Andernfalls, wenn die Google Play-Dienste-Version des Nutzers zu niedrig ist, löst das System eine ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED-Ausnahme aus.

Fitnessdaten abonnieren

Wenn Sie die Erfassung von Schrittdaten im Hintergrund anfordern möchten, verwenden Sie die Methode subscribe, wie im folgenden Code-Snippet gezeigt:

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

Fitnessdaten lesen und verarbeiten

Nachdem Sie das Abo abgeschlossen haben, können Sie die Daten mit der Methode readData anfordern. Anschließend können Sie LocalDataPoints aus dem resultierenden LocalDataSet abrufen, indem Sie einen LocalDataReadRequest ausführen, wie im folgenden Code-Snippet gezeigt:

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

Die Datensammlung von LocalRecordingClient wird kontinuierlich aktualisiert. Sie können jederzeit readData verwenden, um die aktuellen Zahlen abzurufen.

Im LocalRecordingClient werden Daten für bis zu 10 Tage gespeichert. Um das Risiko von Datenverlusten zu verringern, können Sie WorkManager verwenden, um die Daten regelmäßig im Hintergrund zu erfassen.

Fitnessdaten abbestellen

Um Ressourcen freizugeben, sollten Sie die Erfassung von Sensordaten beenden, wenn Ihre App sie nicht mehr benötigt. So kündigen Sie das Abo mit der Methode 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)
  }