Training mit TrainClient aufzeichnen

Health Services bietet erstklassigen Support für Trainings-Apps über die ExerciseClient Mit ExerciseClient kann deine App festlegen, wann Training läuft, füge Trainingsziele hinzu und erhalte Updates zum Training Status, Trainingsereignisse, oder andere gewünschte Messwerte. Weitere Informationen finden Sie in der vollständigen Liste der Trainingstypen die das Gesundheitswesen unterstützt.

Weitere Informationen finden Sie in der Übungsbeispiel auf GitHub.

Abhängigkeiten hinzufügen

Wenn Sie eine Abhängigkeit von Health Services hinzufügen möchten, müssen Sie das Google Maven-Repository hinzufügen zu Ihrem Projekt hinzufügen. Weitere Informationen finden Sie unter Maven-Repository von Google.

Fügen Sie dann in der Datei build.gradle auf Modulebene die folgende Abhängigkeit hinzu:

Groovig

dependencies {
    implementation "androidx.health:health-services-client:1.1.0-alpha03"
}

Kotlin

dependencies {
    implementation("androidx.health:health-services-client:1.1.0-alpha03")
}

App-Struktur

Verwenden Sie die folgende App-Struktur, wenn Sie eine Trainings-App mit Gesundheitsdienste:

Bei der Vorbereitung auf ein Training und während des Trainings kann aus verschiedenen Gründen gestoppt werden. Der Nutzer wechselt möglicherweise zu einer anderen App oder kehren Sie zum Zifferblatt zurück. Das System zeigt möglicherweise etwas über Ihrem oder der Bildschirm schaltet sich nach einer bestimmten Zeit der Inaktivität möglicherweise aus. Eine kontinuierlich laufende ForegroundService verwenden in Verbindung mit ExerciseClient verwenden, um einen korrekten Betrieb für den gesamten Training.

Mit einem ForegroundService können Sie die Ongoing Activity API nutzen, um eine Anzeige auf der Smartwatch-Oberfläche angezeigt, Training.

Es ist wichtig, dass Sie Ihre Standortdaten im Vordergrund entsprechend anfordern. . Geben Sie in der Manifestdatei den erforderlichen Dienst im Vordergrund an. Typen und Berechtigungen:

<manifest ...>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application ...>
    
      <!-- If your app is designed only for devices that run Wear OS 4
           or lower, use android:foregroundServiceType="location" instead. -->
      <service
          android:name=".MyExerciseSessionRecorder"
          android:foregroundServiceType="health|location">
      </service>
      
    </application>
</manifest>

Verwenden Sie AmbientLifecycleObserver für deine Pre-Workout-Aktivität, die den prepareExercise()-Aufruf und für deine Trainingsaktivität. Aktualisieren Sie das Display jedoch nicht während des Trainings. im Inaktivmodus: Dies liegt daran, dass die Gesundheitsdienste Trainingsdaten stapeln. wenn sich der Bildschirm des Geräts im Inaktivmodus befindet, um Strom zu sparen und die Informationen Die angezeigte Version ist möglicherweise nicht aktuell. Während des Trainings kannst du Daten anzeigen, die für dein mit aktuellen Informationen oder einem leeren Bildschirm.

Funktionen prüfen

Jede ExerciseType unterstützt bestimmte Datentypen für Messwerte und für Trainingsziele. Prüfen Sie diese Funktionen beim Start, da sie je nach auf dem Gerät. Möglicherweise unterstützt ein Gerät eine bestimmte Trainingsart nicht oder eine bestimmte Funktion unterstützen, z. B. die automatische Pause. Außerdem sind die Funktionen eines Geräts kann sich im Laufe der Zeit ändern, beispielsweise nach einem Softwareupdate.

Fragen Sie beim Start der App die Gerätefunktionen ab und speichern und verarbeiten Sie Folgendes:

  • Die von der Plattform unterstützten Übungen.
  • Die Funktionen, die für jede Übung unterstützt werden.
  • Die für jede Übung unterstützten Datentypen.
  • Die für jeden dieser Datentypen erforderlichen Berechtigungen.

ExerciseCapabilities.getExerciseTypeCapabilities() verwenden mit um zu sehen, welche Messwerte du anfordern kannst, Trainingsziele, die du konfigurieren kannst, und welche anderen Funktionen für für diesen Typ. Dies wird im folgenden Beispiel gezeigt:

val healthClient = HealthServices.getClient(this /*context*/)
val exerciseClient = healthClient.exerciseClient
lifecycleScope.launch {
    val capabilities = exerciseClient.getCapabilitiesAsync().await()
    if (ExerciseType.RUNNING in capabilities.supportedExerciseTypes) {
        runningCapabilities =
            capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
    }
}

In der zurückgegebenen ExerciseTypeCapabilities supportedDataTypes werden die Datentypen aufgelistet, für die Sie Daten anfordern können. Das ist von Gerät zu Gerät unterschiedlich. Achten Sie darauf, keine DataType anzufordern, die nicht unterstützt werden. Andernfalls wird Ihre Anfrage möglicherweise scheitern.

Verwenden Sie die Methode supportedGoals und supportedMilestones um zu bestimmen, ob die Übung ein Trainingsziel unterstützen kann, die Sie erstellen möchten.

Wenn der Nutzer in Ihrer App die automatische Pause muss überprüft werden, ob diese Funktion vom Gerät mit supportsAutoPauseAndResume ExerciseClient lehnt Anfragen ab, die im .

Im folgenden Beispiel wird die Unterstützung des Datentyps HEART_RATE_BPM geprüft. die Funktion STEPS_TOTAL für das Zielvorhaben und die Funktion für die automatische Pause:

// Whether we can request heart rate metrics.
supportsHeartRate = DataType.HEART_RATE_BPM in runningCapabilities.supportedDataTypes

// Whether we can make a one-time goal for aggregate steps.
val stepGoals = runningCapabilities.supportedGoals[DataType.STEPS_TOTAL]
supportsStepGoals = 
    (stepGoals != null && ComparisonType.GREATER_THAN_OR_EQUAL in stepGoals)

// Whether auto-pause is supported.
val supportsAutoPause = runningCapabilities.supportsAutoPauseAndResume

Für Updates zum Trainingsstatus registrieren

Trainingsupdates werden an einen Zuhörer gesendet. Deine App kann nur eine nicht für jeden einzelnen Hörer. Richte deinen Zuhörer ein, bevor du mit dem Training beginnst, wie im folgenden Beispiel gezeigt. Dein Listener erhält nur Updates zu Übungen, die deiner App gehören.

val callback = object : ExerciseUpdateCallback {
    override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
        val exerciseStateInfo = update.exerciseStateInfo
        val activeDuration = update.activeDurationCheckpoint
        val latestMetrics = update.latestMetrics
        val latestGoals = update.latestAchievedGoals
    }

    override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
        // For ExerciseTypes that support laps, this is called when a lap is marked.
    }

    override fun onAvailabilityChanged(
        dataType: DataType<*, *>,
        availability: Availability
    ) {
        // Called when the availability of a particular DataType changes.
        when {
            availability is LocationAvailability -> // Relates to Location/GPS.
            availability is DataTypeAvailability -> // Relates to another DataType.
        }
    }
}
exerciseClient.setUpdateCallback(callback)

Trainingsdauer verwalten

Die Gesundheitsdienste unterstützen in allen Apps auf auf dem Gerät. Wenn ein Training aufgezeichnet wird und eine andere App mit dem Tracking beginnt eine neue Übung endet, wird die erste beendet.

Bevor du mit dem Training beginnst, solltest du Folgendes tun:

  • Überprüfe, ob ein Training bereits aufgezeichnet wird, und entsprechend zu reagieren. Nutzer um Bestätigung bitten bevor du eine vorherige Übung überschreibst und mit der Aufzeichnung eines neuen beginnst.

Das folgende Beispiel zeigt, wie du mit getCurrentExerciseInfoAsync:

lifecycleScope.launch {
    val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().await()
    when (exerciseInfo.exerciseTrackedStatus) {
        OTHER_APP_IN_PROGRESS -> // Warn user before continuing, will stop the existing workout.
        OWNED_EXERCISE_IN_PROGRESS -> // This app has an existing workout.
        NO_EXERCISE_IN_PROGRESS -> // Start a fresh workout.
    }
}

Berechtigungen

Wenn du ExerciseClient verwendest, achte darauf, dass deine App die erforderlichen Berechtigungen. Wenn deine App Daten des Typs „LOCATION“ verwendet, musst du dafür sorgen, dass sie die die entsprechenden Berechtigungen haben.

Führen Sie vor dem Aufrufen von prepareExercise() oder startExercise() für alle Datentypen folgende Schritte aus: Gehen Sie so vor:

  • Geben Sie in der Datei AndroidManifest.xml die entsprechenden Berechtigungen für die angeforderten Datentypen an.
  • Prüfen Sie, ob der Nutzer die erforderlichen Berechtigungen gewährt hat. Weitere Informationen finden Sie unter App-Berechtigungen anfordern Gesundheitsdienste lehnt die Anfrage ab, wenn die erforderlichen Berechtigungen noch nicht vorhanden sind. gewährt wird.

Führen Sie zum Abrufen von Standortdaten die folgenden zusätzlichen Schritte aus:

Bereite dich auf ein Training vor

Einige Sensoren, z. B. GPS oder Herzfrequenz, benötigen etwas Zeit, um sich aufzuwärmen, oder der Benutzer möchte vielleicht ihre Daten sehen, bevor sie mit dem Training beginnen. Das optionale Feld prepareExerciseAsync() können sich die Sensoren aufwärmen und Daten empfangen, ohne den Timer für das Training ein. activeDuration ist davon nicht betroffen die Vorbereitungszeit.

Prüfen Sie Folgendes, bevor Sie prepareExerciseAsync() aufrufen:

  • Überprüfen Sie die plattformweite Standorteinstellung. Der Nutzer legt diese Einstellung fest in das Hauptmenü „Einstellungen“ unterscheiden sich von den Berechtigungen auf App-Ebene überprüfen.

    Ist die Einstellung deaktiviert, benachrichtigen Sie den Nutzer, dass er den Zugriff verweigert hat. Standort und bitte ihn, diese Funktion zu aktivieren, wenn deine App einen Standort benötigt.

  • Prüfe, ob deine App Laufzeitberechtigungen für Körpersensoren, Aktivitäten hat die Erkennung und den genauen Standort. Nutzer bei fehlenden Berechtigungen auffordern, Laufzeitberechtigungen und den entsprechenden Kontext. Wenn der Nutzer keine bestimmte Berechtigung haben, entfernen Sie die mit dieser Berechtigung verknüpften Datentypen aus dem Aufruf an prepareExerciseAsync(). Wenn weder die Berechtigung für den Körpersensor noch die Standortermittlung aktiviert ist Rufen Sie nicht prepareExerciseAsync() auf, da der Aufruf zur Vorbereitung speziell für eine stabile Herzfrequenz oder ein GPS-Signal vor Beginn eines Trainings zu erhalten. Die App kann dennoch schrittbasierte Entfernung, Geschwindigkeit, Geschwindigkeit und andere Messwerte abgerufen werden, die diese Berechtigungen benötigen.

So sorgen Sie dafür, dass der Aufruf von prepareExerciseAsync() erfolgreich ist:

  • AmbientLifecycleObserver verwenden für die Pre-Workout-Aktivität, die den Anruf vorbereiten enthält.
  • Rufen Sie prepareExerciseAsync() über Ihren Dienst im Vordergrund auf. Befindet er sich nicht in einem und an den Aktivitätslebenszyklus gebunden ist, kann die Sensorvorbereitung unnötig getötet wurden.
  • Rufen Sie endExercise() auf, um die Sensoren auszuschalten und den Stromverbrauch zu reduzieren, wenn der Nutzer navigiert von der Pre-Workout-Aktivität weg.

Das folgende Beispiel zeigt, wie prepareExerciseAsync() aufgerufen wird:

val warmUpConfig = WarmUpConfig(
    ExerciseType.RUNNING,
    setOf(
        DataType.HEART_RATE_BPM,
        DataType.LOCATION
    )
)
// Only necessary to call prepareExerciseAsync if body sensor or location
//permissions are given
exerciseClient.prepareExerciseAsync(warmUpConfig).await()

// Data and availability updates are delivered to the registered listener.

Sobald sich die App im Status PREPARING befindet, wird die Verfügbarkeit des Sensors aktualisiert geliefert in den ExerciseUpdateCallback bis onAvailabilityChanged(). Diese Informationen können dann den Nutzenden angezeigt werden, damit sie entscheiden können, um mit dem Training zu beginnen.

Training starten

Wenn du ein Training starten möchtest, erstelle ein ExerciseConfig, um das Trainingstyp, die Datentypen, für die du Metriken erhalten möchtest, Trainingsziele oder Meilensteine.

Trainingsziele bestehen aus einem DataType und einem . Trainingsziele sind ein einmaliges Ziel, das ausgelöst wird, Bedingung erfüllt ist, z. B. wenn der Nutzer eine bestimmte Strecke zurücklegt. Eine Übung können auch Meilensteine festgelegt werden. Trainingsmeilensteine können mehrfach ausgelöst werden, zum Beispiel jedes Mal, wenn Nutzende über die festgelegte Strecke überschreitet.

Im folgenden Beispiel sehen Sie, wie ein Zielvorhaben für jeden Typ erstellt wird:

const val CALORIES_THRESHOLD = 250.0
const val DISTANCE_THRESHOLD = 1_000.0 // meters

suspend fun startExercise() {
    // Types for which we want to receive metrics.
    val dataTypes = setOf(
        DataType.HEART_RATE_BPM,
        DataType.CALORIES_TOTAL,
        DataType.DISTANCE
    )

    // Create a one-time goal.
    val calorieGoal = ExerciseGoal.createOneTimeGoal(
        DataTypeCondition(
            dataType = DataType.CALORIES_TOTAL,
            threshold = CALORIES_THRESHOLD,
            comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
        )
    )

    // Create a milestone goal. To make a milestone for every kilometer, set the initial
    // threshold to 1km and the period to 1km.
    val distanceGoal = ExerciseGoal.createMilestone(
        condition = DataTypeCondition(
            dataType = DataType.DISTANCE_TOTAL,
            threshold = DISTANCE_THRESHOLD,
            comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
        ),
        period = DISTANCE_THRESHOLD
    )

    val config = ExerciseConfig(
        exerciseType = ExerciseType.RUNNING,
        dataTypes = dataTypes,
        isAutoPauseAndResumeEnabled = false,
        isGpsEnabled = true,
        exerciseGoals = mutableListOf<ExerciseGoal<Double>>(calorieGoal, distanceGoal)
    )
    exerciseClient.startExerciseAsync(config).await()
}

Du kannst auch Runden für alle Trainings markieren. Health Services bietet eine ExerciseLapSummary mit Messwerten, die über den Rundenzeitraum aggregiert wurden.

Das vorherige Beispiel zeigt die Verwendung von isGpsEnabled, was wahr sein muss. wenn Standortdaten angefordert werden. Die Verwendung von GPS kann jedoch auch bei anderen Metriken unterstützen. Wenn ExerciseConfig die Entfernung als DataType angibt, ist dies Standardeinstellung. oder mithilfe von Schritten zur Entfernung von Entfernungen. Durch die optionale Aktivierung von GPS werden die -Informationen können stattdessen zur Schätzung der Entfernung verwendet werden.

Training pausieren, fortsetzen und beenden

Du kannst das Training mit der entsprechenden Methode pausieren, fortsetzen und beenden, z. B. pauseExerciseAsync() oder endExerciseAsync()

Verwende den Status aus ExerciseUpdate als „Source of Truth“. Das Training ist nicht gilt als pausiert, wenn der Aufruf von pauseExerciseAsync() zurückgegeben wird, aber stattdessen wenn dieser Status in der ExerciseUpdate-Nachricht widergespiegelt wird. Das ist besonders die bei UI-Zuständen wichtig sind. Wenn Nutzende die Pause drücken, Pause-Schaltfläche deaktivieren und pauseExerciseAsync() aufrufen bei Gesundheitsdienste. Warten Sie, bis die Gesundheitsdienste die pausierten mit ExerciseUpdate.exerciseStateInfo.state ändern und dann die Schaltfläche um fortzufahren. Das liegt daran, dass es länger dauern kann, bis der Status geliefert wird als der Tastendruck. Wenn Sie also alle Änderungen an der Benutzeroberfläche kann es vorkommen, dass die Benutzeroberfläche nicht mit dem Health Services-Status synchron ist.

Beachten Sie dies in den folgenden Situationen:

  • Die automatische Pause ist aktiviert:Das Training kann pausiert oder gestartet werden, ohne der Nutzerinteraktion.
  • Eine andere App beginnt ein Training:Das Training wird möglicherweise beendet, der Nutzerinteraktion.

Wenn das Training Ihrer App von einer anderen App beendet wird, muss Ihre App anmutig die Beendigung selbst zu übernehmen:

  • Speichere den Teiltrainingsstatus, damit der Fortschritt des Benutzers nicht gelöscht wird.
  • Entferne das Symbol „Laufende Aktivität“ und sende dem Nutzer eine Benachrichtigung, wissen sie, dass ihr Training durch eine andere App beendet wurde.

Behandeln Sie auch Fälle, in denen Berechtigungen während eines während des Trainings. Sie wird mit dem Status isEnded gesendet, wobei ein ExerciseEndReason von AUTO_END_PERMISSION_LOST. Gehen Sie bei diesem Fall ähnlich wie bei der Beendigungsfall: Teilstatus speichern, laufende Aktivität entfernen und eine Benachrichtigung darüber zu senden, was mit dem Nutzer passiert ist.

Das folgende Beispiel zeigt, wie die Beendigung korrekt geprüft wird:

val callback = object : ExerciseUpdateCallback {
    override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
        if (update.exerciseStateInfo.state.isEnded) {
            // Workout has either been ended by the user, or otherwise terminated
        }
        ...
    }
    ...
}

Aktive Dauer verwalten

Während eines Trainings kann eine App die aktive Dauer für das Training. Die App, die Gesundheitsdienste und die Micro-Controller-Einheit des Geräts (MCU) – der Low-Power Verantwortlicher für die Trainingsaufzeichnung – alle müssen synchron sein, mit der aktuellen aktiven Dauer identisch. Um dies zu bewältigen, sendet Health Services eine ActiveDurationCheckpoint, der einen Ankerpunkt darstellt, von dem aus die App den Timer starten.

Da die aktive Dauer vom MCU gesendet wird und nur wenig Zeit angezeigt wird, enthält ActiveDurationCheckpoint zwei Eigenschaften:

  • activeDuration: wie lange das Training aktiv war
  • time: Zeitpunkt, zu dem die aktive Dauer berechnet wurde

Daher kann die aktive Dauer einer Übung in der App mit folgender Gleichung aus ActiveDurationCheckpoint berechnet:

(now() - checkpoint.time) + checkpoint.activeDuration

Dadurch wird das kleine Delta zwischen der Berechnung der aktiven Dauer berücksichtigt, auf dem MCU und gelangen zur App. Damit kann ein Chronometer und dafür sorgen, dass der Timer der App genau auf die Uhrzeit im Gesundheitswesen und im MCU.

Wenn das Training angehalten wird, wartet die App auf einen Neustart des Timers in der Benutzeroberfläche bis die berechnete Zeit über dem aktuell auf der Benutzeroberfläche angezeigten Wert liegt. Das liegt daran, dass das Pausensignal Health Services und die MCU mit einer leichten Verspätung. Wenn die App beispielsweise bei t=10 Sekunden pausiert wird, Die Dienste stellen das Update PAUSED möglicherweise erst bei t=10,2 Sekunden an die Anwendung bereit.

Mit Daten von ExerciseClient arbeiten

Messwerte für die Datentypen, für die sich Ihre App registriert hat, werden in ExerciseUpdate Nachrichten.

Der Prozessor stellt Nachrichten nur dann zu, wenn er wach ist oder wenn ein maximaler Punkt erreicht wird, beispielsweise alle 150 Sekunden. Verlassen Sie sich nicht auf die ExerciseUpdate, um den Chronometer weiter mit der activeDuration. Weitere Informationen finden Sie in der Übungsbeispiel auf GitHub ein Beispiel für die Implementierung eines unabhängigen Chronometers.

Wenn ein Nutzer ein Training beginnt, können ExerciseUpdate-Nachrichten zugestellt werden z. B. jede Sekunde. Zu Beginn des Trainings könnte der Bildschirm ausschalten. Die Gesundheitsdienste können dann Daten seltener bereitstellen, die Stichproben bleiben aber unverändert. um zu verhindern, dass der Hauptprozessor aktiviert wird. Wenn Nutzende den Bildschirm schaut, werden alle Daten, die gerade verarbeitet werden, sofort an Ihre App ausgeliefert.

Batchverarbeitungsrate steuern

In einigen Szenarien möchten Sie die Häufigkeit festlegen, mit der Ihre App empfängt bestimmte Datentypen, während der Bildschirm ausgeschaltet ist. A BatchingMode -Objekt ermöglicht Ihrer App das Überschreiben des standardmäßigen Batchverhaltens, um Daten abzurufen häufigere Lieferungen.

So konfigurieren Sie die Batchrate:

  1. Prüfen Sie, ob die jeweilige BatchingMode-Definition vom Gerät unterstützt wird:

    // Confirm BatchingMode support to control heart rate stream to phone.
    suspend fun supportsHrWorkoutCompanionMode(): Boolean {
        val capabilities = exerciseClient.getCapabilities()
        return BatchingMode.HEART_RATE_5_SECONDS in
                capabilities.supportedBatchingModeOverrides
    }
    
  2. Geben Sie an, dass das ExerciseConfig-Objekt eine bestimmte BatchingMode, wie im folgenden Code-Snippet gezeigt.

    val config = ExerciseConfig(
        exerciseType = ExerciseType.WORKOUT,
        dataTypes = setOf(
            DataType.HEART_RATE_BPM,
            DataType.TOTAL_CALORIES
        ),
        // ...
        batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    )
    
  3. Optional kannst du BatchingMode während des Trainings dynamisch konfigurieren. statt ein bestimmtes Batch-Verhalten für die gesamte Dauer beizubehalten, des Trainings:

    val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
    
  4. So löschen Sie das benutzerdefinierte BatchingMode und kehren zum Standardverhalten zurück: ein leeres Set an exerciseClient.overrideBatchingModesForActiveExercise().

Zeitstempel

Der Zeitpunkt jedes Datenpunkts steht für die Dauer seit dem Gerät gestartet wurden. So wandeln Sie dies in einen Zeitstempel um:

val bootInstant =
    Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())

Dieser Wert kann dann mit getStartInstant() verwendet werden oder getEndInstant() für jeden Datenpunkt.

Datengenauigkeit

Bei einigen Datentypen können Genauigkeitsinformationen mit jedem Datenpunkt verknüpft sein. Dies wird in der Property accuracy dargestellt.

Die Klassen HrAccuracy und LocationAccuracy können für die HEART_RATE_BPM bzw. LOCATION. Verwenden Sie, sofern vorhanden, den Eigenschaft accuracy, um zu bestimmen, ob jeder Datenpunkt ausreichend ist für Ihre Anwendung zu verbessern.

Daten speichern und hochladen

Mit Room bleiben die von Health bereitgestellten Daten erhalten Dienste. Der Datenupload erfolgt am Ende der Übung mithilfe eines Mechanismus wie Work Manager. Dadurch wird sichergestellt, dass Netzwerkaufrufe zum Hochladen von Daten bis zum Ende der Übung den Stromverbrauch während des Trainings zu minimieren und die Arbeit zu vereinfachen.

Liste zur Überprüfung der Einbindung

Bevor Sie Ihre App veröffentlichen, in der Health Services verwendet wird ExerciseClient, Beratung die folgende Checkliste durch, um einige häufige Probleme zu vermeiden. Sind die folgenden Voraussetzungen erfüllt?

  • Deine App prüft die Funktionen des Trainingstyps und der Funktionen des Geräts jedes Mal angezeigt, wenn die App ausgeführt wird. So kannst du erkennen, wenn ein bestimmtes Gerät oder eine bestimmte Übung diese Funktion nicht unterstützt Datentypen, die Ihre App benötigt.
  • Sie fordern und verwalten die erforderlichen Berechtigungen und geben diese in Ihre Manifestdatei. Bevor prepareExerciseAsync() aufgerufen wird, muss deine App bestätigt, dass die Laufzeitberechtigungen gewährt wurden.
  • Deine App verwendet getCurrentExerciseInfoAsync() für die Fälle, in denen:
    • Es wird bereits ein Training aufgezeichnet und deine App überschreibt das vorherige Übung.
    • Eine andere App hat dein Training beendet. Das kann passieren, wenn Nutzende öffnet die App erneut und der Nutzer wird in einer Nachricht darüber informiert, dass die Übung weil eine andere App übernommen wurde.
  • Wenn Sie LOCATION-Daten verwenden:
    • Deine App erhält eine ForegroundService mit der entsprechenden foregroundServiceType während der gesamten Übung (einschließlich Anrufvorbereitung).
    • Überprüfe mit der folgenden Methode, ob GPS auf dem Gerät aktiviert ist: isProviderEnabled(LocationManager.GPS_PROVIDER) und fordert den Nutzer dazu auf, öffne gegebenenfalls die Standorteinstellungen.
    • Für anspruchsvolle Anwendungsfälle, bei denen der Empfang von Standortdaten mit ist Latenz von großer Bedeutung, sollten Sie erwägen, die fusionierte Standortanbieter (FLP) und ihre Daten als anfängliche Standortkorrektur zu verwenden. Wenn stabiler Standortinformationen werden von Health Services bereitgestellt. Verwenden Sie stattdessen diese Daten. bei FLP.
  • Wenn für Ihre App ein Datenupload erforderlich ist, werden alle Netzwerkaufrufe zum Hochladen von Daten bis das Training beendet ist. Andernfalls können Sie während der Übung App alle notwendigen Netzwerkaufrufe sparsam durchführt.