Rejestrowanie ćwiczenia w Ćwiczeniem klienta

Health Services zapewnia wsparcie dla aplikacji treningowych ExerciseClient Dzięki ExerciseClient Twoja aplikacja może kontrolować, kiedy ćwiczenie w toku, dodaj cele ćwiczeniowe i otrzymuj powiadomienia o ćwiczeniu stan, zdarzenia ćwiczeń, lub inne wskaźniki. Aby dowiedzieć się więcej, zapoznaj się z pełną listą rodzaje ćwiczeń obsługiwanych przez Usługi zdrowotne.

Zobacz Przykład ćwiczenia w GitHubie.

Dodaj zależności

Aby dodać zależność od usług zdrowotnych, musisz dodać repozytorium Google Maven do swojego projektu. Więcej informacji: repozytorium Google Maven.

Następnie w pliku build.gradle na poziomie modułu dodaj tę zależność:

Odlotowe

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

Kotlin

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

Struktura aplikacji

Tworząc aplikację do ćwiczeń z użyciem tej struktury: Usługi medyczne:

Podczas przygotowywania i w trakcie treningu Twoja aktywność mogą zostać zatrzymane z różnych powodów. Użytkownik może przełączyć się na inną aplikację. lub wróć do tarczy zegarka. System może wyświetlić coś na aktywności lub ekran może się wyłączyć po określonym czasie. Użyj stale działającego adresu ForegroundService w połączeniu z ExerciseClient, by zapewnić prawidłowe działanie w całym trening.

Użycie interfejsu ForegroundService umożliwia korzystanie z interfejsu Ongoing Activity API do pokazywania wskaźnik na powierzchni zegarka, umożliwiając użytkownikowi szybki powrót do trening.

Musisz prawidłowo prosić o dostęp do danych o lokalizacji na pierwszym planie posprzedażna. W pliku manifestu wskaż niezbędną usługę działającą na pierwszym planie uprawnienia:

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

Używaj AmbientLifecycleObserver na ćwiczenia przedtreningowe, które obejmują rozmowę prepareExercise() za aktywność treningową. Nie aktualizuj wyświetlacza w trakcie treningu w trybie nieaktywnym: wynika to z faktu, że Usługi medyczne zbierają dane o treningach gdy ekran urządzenia jest w trybie nieaktywnym, aby oszczędzać energię, informacje mogą nie być aktualne. Podczas treningu pokazuj dane, które mogą przydać się z aktualnymi informacjami lub pustym ekranem.

Sprawdź możliwości

Każda ExerciseType obsługuje określone typy danych oraz celów ćwiczeń. Sprawdź te możliwości podczas uruchamiania, ponieważ mogą się one różnić w zależności od na urządzeniu. Urządzenie może nie obsługiwać określonego rodzaju ćwiczeń lub nie obsługiwać go obsługuje określoną funkcję, taką jak automatyczne wstrzymywanie. Dodatkowo funkcje urządzenia mogą z czasem ulec zmianie, na przykład po aktualizacji oprogramowania.

Po uruchomieniu aplikacji zapytania o możliwości urządzenia oraz przechowywanie i przetwarzanie :

  • Ćwiczenia obsługiwane przez platformę.
  • Funkcje obsługiwane w poszczególnych ćwiczeniach.
  • Typy danych obsługiwane w przypadku każdego ćwiczenia.
  • Uprawnienia wymagane w przypadku każdego z tych typów danych.

Używaj aplikacji ExerciseCapabilities.getExerciseTypeCapabilities() w: wybranego rodzaju ćwiczenia, aby zobaczyć, jakie dane możesz uzyskać, cele ćwiczeń, które możesz skonfigurować, i inne funkcje, dla których są dostępne tego typu. Widać to w tym przykładzie:

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

W zwróconym urządzeniu ExerciseTypeCapabilities supportedDataTypes. zawiera listę typów danych, o które możesz poprosić. To zależy od urządzenia, więc pamiętaj, aby nie wysyłać prośby o nieobsługiwaną właściwość DataType. W przeciwnym razie Twoja prośba może niepowodzenie.

Użyj supportedGoals oraz supportedMilestones pól wyboru, aby określić, czy ćwiczenie wspiera realizację celu, co użytkownik chce stworzyć.

Jeśli Twoja aplikacja umożliwia użytkownikowi automatyczne wstrzymywanie, musi sprawdzić, czy ta funkcja jest obsługiwana przez urządzenie supportsAutoPauseAndResume ExerciseClient odrzuca żądania, które nie są obsługiwane w urządzenia.

Poniższy przykład pokazuje obsługę typu danych HEART_RATE_BPM. funkcję celu STEPS_TOTAL oraz funkcję automatycznego wstrzymywania:

// 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

Zarejestruj się, aby otrzymywać aktualizacje stanu ćwiczenia

Aktualizacje dotyczące ćwiczeń są dostarczane słuchaczowi. Aplikacja może zarejestrować tylko tylko do 1 detektora. Przed rozpoczęciem treningu skonfiguruj słuchawkę. jak w poniższym przykładzie. Słuchacz otrzymuje tylko powiadomienia o ćwiczeniach utworzonych przez Twoją aplikację.

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)

Zarządzaj czasem trwania ćwiczeń

Usługi zdrowotne obsługują maksymalnie 1 ćwiczenie naraz we wszystkich aplikacjach na urządzenia. Jeśli ćwiczenie jest śledzone, a inna aplikacja rozpoczyna śledzenie nowe ćwiczenie, pierwsze ćwiczenie się zakończy.

Przed rozpoczęciem ćwiczenia wykonaj następujące czynności:

  • Sprawdź, czy ćwiczenie jest już śledzone, i odpowiednio zareagować. Na przykład poproś użytkownika o potwierdzenie przed zastąpieniem poprzedniego i rozpoczęciem śledzenia nowego.

Z przykładu poniżej dowiesz się, jak sprawdzić, czy masz już ćwiczenie z 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.
    }
}

Uprawnienia

Gdy korzystasz z narzędzia ExerciseClient, dopilnuj, aby aplikacja prosiła o zgodę na przetwarzanie danych i utrzymywała niezbędnych uprawnień. Jeśli aplikacja używa danych LOCATION, upewnij się, że prosi ona o zgodę na przetwarzanie danych i obsługuje odpowiednie uprawnienia.

W przypadku wszystkich typów danych, zanim zadzwonisz pod numer prepareExercise() lub startExercise(), wykonaj te czynności:

  • Określ odpowiednie uprawnienia dla żądanych typów danych w pliku AndroidManifest.xml.
  • Sprawdź, czy użytkownik przyznał niezbędne uprawnienia. Więcej informacji: Poproś o przyznanie uprawnień aplikacji. Usługi medyczne odrzuci prośbę, jeśli niezbędne uprawnienia nie zostały jeszcze przyznane.

W przypadku danych o lokalizacji wykonaj te dodatkowe czynności:

Przygotuj się do treningu

Niektóre czujniki, takie jak GPS czy tętno, mogą potrzebować chwili na rozgrzewanie się. Użytkownik może też mogą chcieć sprawdzić swoje dane przed rozpoczęciem treningu. Parametr opcjonalny prepareExerciseAsync() pozwala czujnikom rozgrzewać się i odbierać dane bez uruchamiania minutnik na trening. activeDuration nie ma wpływu na to ustawienie w czasie przygotowań.

Zanim zadzwonisz pod numer prepareExerciseAsync(), sprawdź te kwestie:

  • Sprawdź ustawienie lokalizacji na całej platformie. Użytkownik kontroluje to ustawienie w główne menu Ustawienia; są one inne niż uprawnienia na poziomie aplikacji, sprawdzić.

    Jeśli to ustawienie jest wyłączone, powiadom użytkownika o odmowie dostępu lokalizacji i poproś o jej włączenie, jeśli aplikacja wymaga dostępu do lokalizacji.

  • Potwierdź, że aplikacja ma uprawnienia w czasie działania dotyczące czujników na ciele i aktywności rozpoznawanie twarzy i dokładną lokalizację. Jeśli nie masz uprawnień, poproś użytkownika o podanie uprawnień w czasie działania, które zapewniają odpowiedni kontekst. Jeśli użytkownik nie przyzna usuń powiązane z nim typy danych, z połączenia z numerem prepareExerciseAsync(). Jeśli brak dostępu do czujnika na ciele ani dostępu do lokalizacji nie dzwoń pod numer prepareExerciseAsync(), bo rozmowa jest przeznaczona dla uzyskanie stabilnego tętna lub sygnału GPS przed rozpoczęciem ćwiczenia. Aplikacja nadal może wyświetlać dystans, tempo, prędkość i inne dane, które nie wymagają tych uprawnień.

.

Aby wywołanie funkcji prepareExerciseAsync() się udało:

  • Użyj formatu AmbientLifecycleObserver na ćwiczenia przedtreningowe, które obejmują rozmowę przygotowującą.
  • Wywołaj funkcję prepareExerciseAsync() z usługi na pierwszym planie. Jeśli nie znajduje się w i jest powiązana z cyklem życia aktywności, przygotowanie czujnika niepotrzebnie zabici.
  • Wywołaj funkcję endExercise(), aby wyłączyć czujniki i zmniejszyć zużycie energii, jeśli użytkownik wyłącza aktywność przed treningiem.

Ten przykład pokazuje, jak zadzwonić pod numer prepareExerciseAsync():

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.

Gdy aplikacja będzie w stanie PREPARING, aktualizacje dostępności czujnika będą dostawa: ExerciseUpdateCallback do onAvailabilityChanged(). Te informacje można przedstawić użytkownikowi, by mógł zdecydować, czy aby rozpocząć trening.

Rozpocznij trening

Jeśli chcesz rozpocząć ćwiczenie, utwórz ExerciseConfig, aby skonfigurować rodzaj ćwiczenia, typy danych, dla których chcesz otrzymywać dane, cele ćwiczenia lub kamienie milowe.

Cele ćwiczeń składają się z DataType i . Cele ćwiczeniowe to jednorazowe cele, które są aktywowane, gdy zostanie spełniony warunek, np. gdy użytkownik przebiegnie określoną odległość. Ćwiczenie możesz też określić kamienie milowe. Etapy ćwiczenia mogą być wyzwalane wiele razy, Na przykład gdy użytkownik pokonuje ustalony dystans.

Z przykładu poniżej dowiesz się, jak utworzyć po 1 celu każdego typu:

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

Możesz też zaznaczać okrążenia dla wszystkich ćwiczeń. Usługi zdrowotne oferują ExerciseLapSummary z danymi zagregowanymi z okresu okrążenia.

Poprzedni przykład pokazuje użycie funkcji isGpsEnabled, która musi być spełniony gdy prosisz o dane o lokalizacji. Pamiętaj jednak, że GPS pomaga też interpretować inne dane. Wartość domyślna, jeśli ExerciseConfig określa odległość w postaci DataType, do szacowania dystansu za pomocą kroków. Po włączeniu opcjonalnych ustawień GPS lokalizacja można użyć tych informacji do szacowania odległości.

Wstrzymywanie, wznawianie i kończenie treningu

Możesz wstrzymywać, wznawiać i kończyć treningi, korzystając z odpowiedniej metody, np. pauseExerciseAsync() lub endExerciseAsync()

Użyj stanu z ExerciseUpdate jako źródła informacji. To nie jest trening uznaje się za wstrzymane, gdy wywołanie pauseExerciseAsync() powraca, ale zamiast tego po odzwierciedleniu tego stanu w komunikacie ExerciseUpdate. Jest to szczególnie ważne, które warto wziąć pod uwagę w przypadku stanów UI. Jeśli użytkownik naciśnie „Wstrzymaj”, wyłącz przycisk pauzy i zadzwoń do: pauseExerciseAsync() Usługi medyczne. Poczekaj, aż usługi zdrowotne zostaną wstrzymane stan za pomocą ExerciseUpdate.exerciseStateInfo.state, a następnie przełącz przycisk aby wznowić. Wynika to z faktu, że aktualizacja stanu usług medycznych może potrwać dłużej niż naciśnięcie przycisku, więc jeśli powiążesz wszystkie zmiany w interfejsie interfejs użytkownika może nie być zsynchronizowany ze stanem usług zdrowotnych.

Pamiętaj o tym w tych sytuacjach:

  • Automatyczne wstrzymywanie jest włączone: trening może się zatrzymać lub rozpocząć bez. interakcji użytkownika.
  • Inna aplikacja rozpoczyna trening: trening może zostać przerwany bez interakcji użytkownika.

Jeśli trening w aplikacji zakończy się przez inną aplikację, musi ona działać płynnie obsługuje zakończenie:

  • Zapisz stan częściowego treningu, aby postępy użytkownika nie zostały skasowane.
  • Usuń ikonę bieżącej aktywności i wyślij do użytkownika powiadomienie o możliwości wiedzą, że trening zakończył się przez inną aplikację.

Zajmij się także przypadkiem unieważnienia uprawnień trwającego ćwiczenia. Jest ona wysyłana za pomocą stanu isEnded z parametrem ExerciseEndReason. z AUTO_END_PERMISSION_LOST. Wykonaj to w sposób podobny do przypadek zakończenia: zapisz częściowy stan, usuń bieżącą aktywność i wysyłać powiadomienie o tym, co się stało z użytkownikiem.

Ten przykład pokazuje, jak sprawdzić, czy film został zamknięty:

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

Zarządzaj aktywnym czasem trwania

W trakcie ćwiczenia aplikacja może wyświetlać czas trwania trening. Aplikacja, usługi zdrowotne i jednostka mikrokontrolera urządzenia (MCU) – o niskim zużyciu energii. procesora odpowiedzialnego za śledzenie ćwiczeń—wszystkie muszą być zsynchronizowane taki sam bieżący czas trwania. Aby ułatwić sobie to zadanie, służby zdrowia wysyłają ActiveDurationCheckpoint stanowiący punkt zakotwiczenia, z którego aplikacja może uruchomić minutnik.

Ponieważ aktywny czas trwania jest wysyłany z MCU i może zająć niewielkim czas pojawienia się w aplikacji, właściwość ActiveDurationCheckpoint zawiera dwie właściwości:

  • activeDuration: jak długo było aktywne ćwiczenie
  • time: czas obliczenia aktywności.

Dlatego w aplikacji aktywny czas trwania ćwiczenia może być obliczono według wzoru (ActiveDurationCheckpoint) za pomocą następującego równania:

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

Uwzględnia to małą różnicę między obliczonym czasem trwania aktywności. na MCU i otwarcie aplikacji. Pozwala to wyświetlić licznik czasu w aplikacji i pilnują, aby minutnik aplikacji idealnie odpowiadał na czas w sektorze opieki zdrowotnej i MCU.

Jeśli ćwiczenie jest wstrzymane, aplikacja czeka na zrestartowanie minutnika w interfejsie. do czasu, gdy obliczony czas minie dłużej niż wyświetlany aktualnie w interfejsie. Dzieje się tak, ponieważ sygnał wstrzymania dociera do służb medycznych i MCU z niewielkie opóźnienie. Na przykład: jeśli aplikacja zostanie wstrzymana na t=10 sekund, sekcja Zdrowie Usługi mogą pobrać aktualizację PAUSED do aplikacji dopiero po 10,2 sekundy.

Praca z danymi z ĆwiczeniaClient

Wskaźniki dotyczące typów danych, dla których aplikacja jest zarejestrowana, są dostarczane ExerciseUpdate wiadomości.

Procesor dostarcza wiadomości tylko wtedy, gdy jest wybudzony lub gdy maksymalna liczba zgłoszeń okresu, np. co 150 sekund. Nie polegaj na Częstotliwość ExerciseUpdate, aby przewijać chronometr za pomocą activeDuration Zobacz Przykład ćwiczenia znajdziesz na GitHubie przykład implementacji niezależnego chronometru.

Gdy użytkownik rozpocznie trening, może zostać dostarczona ExerciseUpdate wiadomość często, na przykład co sekundę. Gdy użytkownik rozpocznie trening, ekran może wyłącz. Usługi zdrowotne mogą następnie dostarczać dane rzadziej, ale nadal są próbkowane bez zmian tak, by nie wybudzać głównego procesora. Gdy użytkownik Gdy patrzy na ekran, wszelkie dane w trakcie grupowania są natychmiast do Twojej aplikacji.

Kontroluj szybkość grupowania

W niektórych sytuacjach warto kontrolować częstotliwość wyświetlania odbiera określone typy danych, gdy ekran jest wyłączony. O BatchingMode umożliwia aplikacji zastępowanie domyślnego sposobu grupowania w celu pobrania danych jest realizowana częściej.

Aby skonfigurować szybkość grupowania, wykonaj te czynności:

  1. Sprawdź, czy urządzenie obsługuje konkretną definicję atrybutu BatchingMode:

    // 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. Określ, że obiekt ExerciseConfig powinien używać określonej BatchingMode zgodnie z poniższym fragmentem kodu.

    val config = ExerciseConfig(
        exerciseType = ExerciseType.WORKOUT,
        dataTypes = setOf(
            DataType.HEART_RATE_BPM,
            DataType.TOTAL_CALORIES
        ),
        // ...
        batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    )
    
  3. Opcjonalnie możesz dynamicznie skonfigurować BatchingMode podczas treningu, , zamiast określonego działania grupowania utrzymują się przez cały czas trwania treningu:

    val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
    
  4. Aby wyczyścić dostosowany BatchingMode i przywrócić działanie domyślne, przekazać pusty zbiór do exerciseClient.overrideBatchingModesForActiveExercise()

Sygnatury czasowe

Do określenia momentu każdego punktu danych odpowiada czas, który upłynął od momentu, gdy urządzenie uruchomiono urządzenie. Aby przekonwertować to na sygnaturę czasową, wykonaj te czynności:

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

Tej wartości można używać z parametrem getStartInstant() lub getEndInstant() dla każdego punktu danych.

Dokładność danych

Niektóre typy danych mogą mieć informacje o dokładności powiązane z każdym punktem danych. Opcja ta znajduje się we właściwości accuracy.

Klasy HrAccuracy i LocationAccuracy mogą być wypełnione dla parametru Typy danych HEART_RATE_BPM i LOCATION. Jeśli ta opcja jest dostępna, użyj funkcji accuracy do określenia, czy każdy punkt danych jest wystarczający dla Twojej aplikacji.

Przechowywanie i przesyłanie danych

Użyj opcji Room, aby zachować dane dostarczone z aplikacji Health Usługi. Przesyłanie danych ma miejsce na końcu ćwiczenia za pomocą mechanizmu takich jak Menedżer pracy. Dzięki temu masz pewność, że żądania sieciowe dotyczące przesyłania danych są odraczane do zakończenia ćwiczenia, minimalizując zużycie energii podczas ćwiczeń i upraszczając pracę.

Lista kontrolna integracji

Zanim opublikujesz aplikację, która korzysta z funkcji związanych z usługami zdrowotnymi ExerciseClient, konsultuj Poniższa lista kontrolna pomoże Ci uniknąć niektórych często spotykanych problemów. Sprawdź, czy:

  • Aplikacja sprawdza jej możliwości typu ćwiczenia i możliwości urządzenia przy każdym uruchomieniu aplikacji. Dzięki temu możesz wykryć, że dane urządzenie lub ćwiczenie go nie obsługuje. typów danych, których potrzebuje Twoja aplikacja.
  • Prosisz o niezbędne uprawnienia i utrzymujesz je oraz określasz w pliku manifestu. Zanim zadzwonisz pod numer prepareExerciseAsync(), Twoja aplikacja potwierdza przyznanie uprawnień w czasie działania.
  • Twoja aplikacja używa getCurrentExerciseInfoAsync() do obsługi przypadków, w których:
      .
    • Ćwiczenie jest już śledzone, a aplikacja zastępuje poprzednie ćwiczenia.
    • Inna aplikacja przerwała ćwiczenie. Może się tak zdarzyć, gdy użytkownik ponownie uruchamia aplikację, ale pojawia się komunikat wyjaśniający, że ćwiczenie przestała działać, bo przejęła ją inna aplikacja.
  • Jeśli korzystasz z danych LOCATION:
    • Aplikacja zachowuje poziom ForegroundService z odpowiednimi wartościami: foregroundServiceType przez cały czas trwania ćwiczenia (w tym rozmowy przygotowującej).
    • Sprawdź, czy GPS jest włączony w urządzeniu, isProviderEnabled(LocationManager.GPS_PROVIDER) i zachęca użytkownika do otwórz ustawienia lokalizacji, jeśli to konieczne.
    • Do wymagających zastosowań, w których otrzymujesz dane o lokalizacji z niskim czas oczekiwania jest bardzo ważny, rozważ zintegrowanie funkcji Fused Dostawca lokalizacji (FLP) i używaniu tych danych jako wstępnej poprawki lokalizacji. W przypadku większej stabilności informacje o lokalizacji są dostępne w usługach zdrowotnych, użyj ich zamiast FLP.
  • Jeśli Twoja aplikacja wymaga przesyłania danych, wszystkie wywołania sieciowe do przesyłania danych są odroczone do zakończenia ćwiczenia. W przeciwnym razie podczas ćwiczenia oszczędnie wykonuje niezbędne połączenia sieciowe.
. .