Usługi zdrowotne zapewniają najwyższej klasy wsparcie dla aplikacji do ćwiczeń za pomocą interfejsu ExerciseClient
.
Dzięki ExerciseClient
aplikacja może kontrolować czas trwania ćwiczeń, dodawać cele związane z ćwiczeniami i otrzymywać aktualne informacje o stanie ćwiczenia, zdarzeniach związanych z ćwiczeniami i innych istotnych danych. Aby dowiedzieć się więcej, zapoznaj się z pełną listą typów ćwiczeń obsługiwanych przez usługi zdrowotne.
Zobacz przykładowe ćwiczenie na GitHubie.
Dodaj zależności
Aby dodać zależność od usług zdrowotnych, musisz dodać do projektu repozytorium Google Maven. Więcej informacji znajdziesz w repozytorium Google Maven.
Następnie w pliku build.gradle
na poziomie modułu dodaj tę zależność:
Odlotowy
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ń w Usługach medycznych, użyj tej struktury:
- Trzymaj ekrany i nawigację w ramach głównej aktywności.
- Zarządzaj stanem treningu, danymi z czujników, bieżącą aktywnością i danymi za pomocą usługi na pierwszym planie.
- Przechowywanie danych w usłudze Sala i przesyłanie danych za pomocą usługi WorkManager.
Kiedy przygotowujesz się do treningu i w trakcie treningu, Twoja aktywność może zostać zatrzymana z różnych powodów. Użytkownik może przełączyć się na inną aplikację
lub wrócić do tarczy zegarka. System może wyświetlić coś u góry informacji
lub wyłączyć ekran po okresie braku aktywności.
Używaj stale uruchomionej funkcji ForegroundService
w połączeniu z parametrem ExerciseClient
, aby zapewnić prawidłowe działanie całego treningu.
ForegroundService
pozwala użyć interfejsu Ongoing Activity API, aby wyświetlić wskaźnik na tarczy zegarka, co pozwoli użytkownikowi szybko wrócić do treningu.
Bardzo ważne jest prawidłowe żądanie danych o lokalizacji w usłudze na pierwszym planie. W pliku manifestu wskaż foregroundServiceType="location"
i określ odpowiednie uprawnienia.
Używaj danych AmbientLifecycleObserver
w przypadku aktywności przed treningiem, która zawiera wywołanie prepareExercise()
i aktywność treningową. Nie aktualizuj jednak wyświetlacza w trakcie treningu, gdy działa on w trybie nieaktywnym. Dzieje się tak, ponieważ usługi zdrowotne zbierają dane treningowe, gdy ekran urządzenia jest w trybie nieaktywnym, aby oszczędzać energię, więc wyświetlane informacje mogą być nieaktualne. Podczas treningu pokazuj dane istotne dla użytkownika, takie jak aktualne informacje lub pusty ekran.
Sprawdź możliwości
Każdy ExerciseType
obsługuje określone typy danych do celów związanych z ćwiczeniami i wskaźników. Sprawdź te możliwości na początku, bo mogą się one różnić w zależności od urządzenia. Urządzenie może nie obsługiwać określonego rodzaju ćwiczeń lub konkretnej funkcji, takiej jak automatyczne wstrzymywanie. Poza tym możliwości urządzenia mogą się zmieniać
z czasem, np. po aktualizacji oprogramowania.
Po uruchomieniu aplikacji wyślij zapytanie o możliwości urządzenia oraz zapisz i przetwarzaj te elementy:
- Ćwiczenia obsługiwane przez platformę.
- Funkcje obsługiwane w przypadku każdego ćwiczenia.
- Typy danych obsługiwane w przypadku każdego ćwiczenia.
- Uprawnienia wymagane w przypadku każdego z tych typów danych.
Użyj operatora ExerciseCapabilities.getExerciseTypeCapabilities()
z wybranym typem ćwiczenia, aby zobaczyć, o jakie wskaźniki możesz prosić, jakie cele możesz skonfigurować i jakie inne funkcje są dostępne w przypadku 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 zwracanym obiekcie ExerciseTypeCapabilities
supportedDataTypes
zawiera listę typów danych, których możesz użyć. Różni się to w zależności od urządzenia, dlatego nie wysyłaj prośby o DataType
, ponieważ może ona zakończyć się niepowodzeniem.
Użyj pól supportedGoals
i supportedMilestones
, aby określić, czy ćwiczenie wspomaga osiągnięcie wyznaczonego przez Ciebie celu.
Jeśli aplikacja umożliwia użytkownikowi korzystanie z automatycznego wstrzymywania, musisz sprawdzić, czy urządzenie obsługuje tę funkcję za pomocą supportsAutoPauseAndResume
.
ExerciseClient
odrzuca żądania, które nie są obsługiwane na urządzeniu.
W tym przykładzie sprawdzisz obsługę typu danych HEART_RATE_BPM
, możliwości celu STEPS_TOTAL
i 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 ćwiczeń
Aktualizacje ćwiczeń są dostarczane do słuchacza. Aplikacja może zarejestrować tylko 1 detektor w danym momencie. Przed rozpoczęciem treningu skonfiguruj słuchawkę w sposób podany w poniższym przykładzie. Słuchacz otrzymuje tylko powiadomienia o ćwiczeniach, które posiada Twoja aplikacja.
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 jedno ćwiczenie jednocześnie we wszystkich aplikacjach na urządzeniu. Jeśli ćwiczenie jest śledzone, a inna aplikacja zacznie śledzić nowe ćwiczenie, pierwsze ćwiczenie zostanie zakończone.
Przed rozpoczęciem ćwiczenia wykonaj następujące czynności:
- Sprawdź, czy ćwiczenie jest już śledzone, i zareaguj odpowiednio. Na przykład poproś użytkownika o potwierdzenie, zanim zastąpisz poprzednie ćwiczenie i zaczniesz śledzić nowe.
Ten przykład pokazuje, jak sprawdzić istniejące ćwiczenie za pomocą 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 używasz funkcji ExerciseClient
, sprawdź, czy aplikacja żąda i utrzymuje niezbędne uprawnienia.
Jeśli aplikacja używa danych LOCATION
, upewnij się, że aplikacja prosi o dostęp do nich i utrzymuje do nich odpowiednie uprawnienia.
W przypadku wszystkich typów danych przed wywołaniem funkcji prepareExercise()
lub startExercise()
wykonaj te czynności:
- W pliku
AndroidManifest.xml
określ odpowiednie uprawnienia dla żądanych typów danych. - Sprawdź, czy użytkownik przyznał niezbędne uprawnienia. Więcej informacji znajdziesz w artykule o wysyłaniu prośby o uprawnienia aplikacji. Usługi zdrowotne odrzucają żądanie, jeśli nie przyznano jeszcze niezbędnych uprawnień.
W przypadku danych o lokalizacji wykonaj te dodatkowe czynności:
- Sprawdź, czy na urządzeniu jest włączony GPS, korzystając z
isProviderEnabled(LocationManager.GPS_PROVIDER)
. W razie potrzeby poproś użytkownika o otworzenie ustawień lokalizacji. - Pilnuj, aby element
ForegroundService
z odpowiednimforegroundServiceType
był utrzymywany przez cały czas trwania treningu.
Przygotuj się do treningu
Niektóre czujniki, takie jak GPS czy tętno, mogą potrzebować chwili na rozgrzewkę, a użytkownik może chcieć sprawdzić swoje dane przed rozpoczęciem treningu. Opcjonalna metoda prepareExerciseAsync()
pozwala czujnikom nagrzewać się i odbierać dane bez uruchamiania stopera przed treningiem. Ten czas przygotowania nie ma wpływu na activeDuration
.
Zanim nawiążesz połączenie z numerem prepareExerciseAsync()
, sprawdź te elementy:
Sprawdź ustawienie lokalizacji na całej platformie. Użytkownik kontroluje to ustawienie w głównym menu Ustawienia. Różni się ono od sprawdzania uprawnień na poziomie aplikacji.
Jeśli to ustawienie jest wyłączone, powiadom użytkownika, że odmówił dostępu do lokalizacji, i poproś o jego włączenie, jeśli aplikacja wymaga dostępu do lokalizacji.
Sprawdź, czy aplikacja ma uprawnienia w czasie działania dotyczące czujników na ciele, rozpoznawania aktywności i dokładnej lokalizacji. W przypadku brakujących uprawnień poproś użytkownika o przyznanie uprawnień czasu działania i podaj odpowiedni kontekst. Jeśli użytkownik nie przyzna określonych uprawnień, usuń typy danych powiązane z tym uprawnieniem z wywołania funkcji
prepareExerciseAsync()
. Jeśli nie przyznano dostępu do czujnika na ciele ani do lokalizacji, nie wywołujprepareExerciseAsync()
, ponieważ rozmowa ta ma na celu uzyskanie stabilnego tętna lub pozycji GPS przed rozpoczęciem ćwiczenia. Aplikacja nadal może pobierać za nią dystans, tempo, prędkość i inne dane, które nie wymagają tych uprawnień.
Aby zapewnić prawidłowe wywołanie metody prepareExerciseAsync()
, wykonaj te czynności:
- Użyj
AmbientLifecycleObserver
w przypadku aktywności przed treningiem, która obejmuje przygotowanie rozmowy. - Wywołaj
prepareExerciseAsync()
z usługi na pierwszym planie. Jeśli nie jest on objęty usługą i jest powiązany z cyklem życia aktywności, przygotowywanie czujnika może zostać niepotrzebnie przerwane. - Wywołaj polecenie
endExercise()
, aby wyłączyć czujniki i zmniejszyć zużycie energii, gdy użytkownik opuści aktywność przed treningiem.
Ten przykład pokazuje, jak wywołać 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 ma stan PREPARING
, aktualizacje informacji o dostępności czujników są dostarczane w klastrach ExerciseUpdateCallback
do onAvailabilityChanged()
.
Informacje te można następnie wyświetlić użytkownikowi, aby mógł zdecydować, czy rozpocząć trening.
Rozpocznij trening
Gdy chcesz rozpocząć ćwiczenie, utwórz ExerciseConfig
, aby skonfigurować typ ćwiczenia, typy danych, o których chcesz otrzymywać wskaźniki, oraz cele związane z ćwiczeniami i etapami milowymi.
Cele ćwiczeń składają się z DataType
i warunku. Cele związane z ćwiczeniami to cel jednorazowy, który jest aktywowany, gdy zostanie spełniony warunek, np. gdy użytkownik przebiegnie określony dystans. Możesz też określić
kamień milowy dotyczący ćwiczenia. Kamienie milowe ćwiczenia mogą być aktywowane wiele razy,
na przykład za każdym razem, gdy użytkownik przebiegnie określony punkt po ustalonym dystansie.
Z przykładu poniżej dowiesz się, jak utworzyć jeden cel 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ż oznaczyć etapy dla wszystkich ćwiczeń. Usługi zdrowotne udostępniają ExerciseLapSummary
ze wskaźnikami zbiorczymi z całego okresu.
Poprzedni przykład przedstawia użycie właściwości isGpsEnabled
, które musi być spełnione podczas żądania danych o lokalizacji. Korzystanie z GPS-u może być też pomocne w przypadku innych danych.
Jeśli ExerciseConfig
określa odległość w polu DataType
, domyślną wartością jest podanie odległości do szacowania za pomocą kroków. Jeśli włączysz GPS, do oszacowania odległości
możesz używać informacji o lokalizacji.
Zatrzymywanie, 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. Trening nie jest uznawany za wstrzymany, gdy wywołanie pauseExerciseAsync()
powróci, tylko gdy zostanie on odzwierciedlony w komunikacie ExerciseUpdate
. Jest to szczególnie ważne, jeśli chodzi o stany interfejsu. Jeśli użytkownik naciśnie przycisk pauzy, wyłącz przycisk pauzy i wywołaj polecenie pauseExerciseAsync()
w usługach zdrowotnych. Poczekaj, aż Usługi zdrowotne osiągną stan wstrzymania za pomocą polecenia ExerciseUpdate.exerciseStateInfo.state
, a następnie przełącz przycisk, aby wznowić. Dzieje się tak, ponieważ aktualizacje stanu usług zdrowotnych mogą trwać dłużej niż naciśnięcie przycisku. Jeśli więc powiążesz wszystkie zmiany w interfejsie z naciśnięciem przycisku, interfejs 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ę zatrzymywać i rozpoczynać bez interakcji użytkownika.
- Inna aplikacja rozpoczyna trening: trening może zostać zakończony bez interakcji użytkownika.
Jeśli trening w Twojej aplikacji zostanie zakończony przez inną aplikację, aplikacja musi płynnie poradzić sobie z zakończeniem:
- Zapisz stan częściowego treningu, aby postępy użytkownika nie zostały wykasowane.
- Usuń ikonę trwającej aktywności i wyślij użytkownikowi powiadomienie o zakończeniu treningu przez inną aplikację.
Weź też pod uwagę przypadki unieważniania uprawnień podczas nieustannego ćwiczenia. Jest ona wysyłana za pomocą stanu isEnded
z ExerciseEndReason
o wartości AUTO_END_PERMISSION_LOST
. Postępuj tak samo jak w przypadku zamknięcia konta: zapisz stan częściowy, usuń ikonę trwającej aktywności i wyślij powiadomienie o tym, co się stało z użytkownikiem.
Z przykładu poniżej dowiesz się, jak sprawdzić, czy konto zostało zamknięte:
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
Podczas ćwiczenia aplikacja może wyświetlać
aktywny czas trwania treningu. Aplikacja, Usługi zdrowotne i Mikrokontroler MCU (MCU), czyli procesor o małej mocy, który odpowiada za monitorowanie ćwiczeń, muszą być zsynchronizowane i zachować przy tym taki sam bieżący czas trwania aktywności. Aby ułatwić zarządzanie tym procesem, Usługi zdrowotne wysyłają kod ActiveDurationCheckpoint
udostępniający punkt zakotwiczenia, od którego aplikacja może uruchamiać licznik czasu.
Czas trwania aktywności jest wysyłany z MCU i może pojawić się w aplikacji dopiero po krótkim czasie, dlatego ActiveDurationCheckpoint
zawiera 2 właściwości:
activeDuration
: czas trwania ćwiczeniatime
: kiedy obliczono aktywny czas trwania.
Dlatego w aplikacji czas trwania aktywności można obliczyć na podstawie wartości ActiveDurationCheckpoint
za pomocą tego równania:
(now() - checkpoint.time) + checkpoint.activeDuration
Uwzględnia niewielką różnicę między aktywnym czasem trwania obliczonym w MCU a momentem pojawienia się w aplikacji. Można to wykorzystać do zapełnienia chronometru w aplikacji i zapewnić, że licznik czasu aplikacji będzie idealnie dopasowany do czasu w MCU.
Jeśli ćwiczenie jest wstrzymane, aplikacja czeka na ponowne uruchomienie stopera w interfejsie, aż obliczony czas upłynie tak długo, jak jest to aktualnie wyświetlane w interfejsie.
Dzieje się tak, ponieważ sygnał wstrzymania dociera do służb zdrowotnych i MCU z niewielkim opóźnieniem. Na przykład, jeśli aplikacja zostanie wstrzymana po t=10 sekundach, usługi Health Services mogą nie dostarczyć do aplikacji aktualizacji PAUSED
do t=10,2 sekundy.
Praca z danymi z Ćwiczenia klienta
Wskaźniki dotyczące typów danych, które zarejestrowała Twoja aplikacja, są dostarczane w wiadomościach ExerciseUpdate
.
Procesor dostarcza wiadomości tylko po wybudzeniu lub po osiągnięciu maksymalnego okresu raportowania, np. co 150 sekund. Nie używaj częstotliwości ExerciseUpdate
do przesuwania chronometru za pomocą activeDuration
. Przykład implementacji niezależnego chronometru znajdziesz w przykładzie ćwiczenia na GitHubie.
Gdy użytkownik rozpoczyna trening, mogą być często dostarczane wiadomości z aplikacji ExerciseUpdate
, np. co sekundę. Gdy użytkownik rozpoczyna trening, ekran może się wyłączyć. Dzięki temu usługi zdrowotne mogą dostarczać dane rzadziej, ale nadal próbkowane są z tą samą częstotliwością, aby uniknąć wybudzenia głównego procesora. Gdy użytkownik patrzy na ekran, wszelkie dane będące w trakcie grupowania są natychmiast dostarczane do aplikacji.
Kontroluj szybkość grupowania
W niektórych sytuacjach możesz chcieć kontrolować częstotliwość, z jaką aplikacja otrzymuje określone typy danych, gdy ekran jest wyłączony. Obiekt BatchingMode
umożliwia aplikacji zastąpienie domyślnego działania wsadowego w celu częstszego dostarczania danych.
Aby skonfigurować szybkość grupowania, wykonaj te czynności:
Sprawdź, czy urządzenie obsługuje konkretną definicję typu
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 }
Określ, że obiekt
ExerciseConfig
powinien używać określonegoBatchingMode
, jak w tym fragmencie kodu.val config = ExerciseConfig( exerciseType = ExerciseType.WORKOUT, dataTypes = setOf( DataType.HEART_RATE_BPM, DataType.TOTAL_CALORIES ), // ... batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS) )
Opcjonalnie możesz dynamicznie konfigurować
BatchingMode
podczas treningu, aby nie utożsamiać się z konkretnym działaniem grupowania przez cały czas jego trwania:val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS) exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
Aby wyczyścić dostosowane
BatchingMode
i przywrócić działanie domyślne, przekaż pusty zestaw do parametruexerciseClient.overrideBatchingModesForActiveExercise()
.
Sygnatury czasowe
Punkt w czasie każdego punktu danych reprezentuje czas od uruchomienia urządzenia. Aby przekonwertować wartość na sygnaturę czasową:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Tej wartości możesz następnie używać w polu getStartInstant()
lub getEndInstant()
dla każdego punktu danych.
Dokładność danych
Niektóre typy danych mogą mieć informacje o dokładności związane z każdym punktem danych.
Reprezentuje ją właściwość accuracy
.
Klasy HrAccuracy
i LocationAccuracy
można wypełniać odpowiednio dla typów danych HEART_RATE_BPM
i LOCATION
. Jeśli jest dostępna, używaj właściwości accuracy
do określania, czy każdy punkt danych ma wystarczająco dużą dokładność na potrzeby Twojej aplikacji.
Przechowywanie i przesyłanie danych
Użyj opcji Sala, aby przechowywać dane dostarczone z usług medycznych. Dane są przesyłane na koniec ćwiczenia za pomocą mechanizmu takiego jak Work Manager. Dzięki temu wywołania sieciowe do przesyłania danych są odraczane do zakończenia ćwiczenia, co minimalizuje zużycie energii w trakcie ćwiczenia i upraszcza pracę.
Lista kontrolna integracji
Zanim opublikujesz aplikację, która korzysta z elementu ExerciseClient
w usługach zdrowotnych, zapoznaj się z tą listą kontrolną, aby uniknąć niektórych typowych problemów.
Sprawdź, czy:
- Przy każdym uruchomieniu aplikacja sprawdza możliwości danego rodzaju ćwiczenia i możliwości urządzenia. Dzięki temu możesz wykryć, czy dane urządzenie lub ćwiczenie nie obsługuje któregoś z typów danych, których potrzebuje Twoja aplikacja.
- Żądasz niezbędnych uprawnień, utrzymujesz je i określasz w pliku manifestu. Przed wywołaniem funkcji
prepareExerciseAsync()
aplikacja potwierdza przyznanie uprawnień w czasie działania. - Aplikacja używa uprawnienia
getCurrentExerciseInfoAsync()
do obsługi przypadków, w których:- Ćwiczenie jest już śledzone, a aplikacja zastępuje poprzednie.
- Inna aplikacja zakończyła ćwiczenie. Może się tak zdarzyć, gdy użytkownik ponownie uruchomi aplikację i zobaczy komunikat informujący o tym, że ćwiczenie zostało przerwane, ponieważ przejęła go inna aplikacja.
- Jeśli używasz danych
LOCATION
:- Aplikacja zachowuje
ForegroundService
z odpowiednimforegroundServiceType
przez cały czas trwania ćwiczenia (w tym rozmowy przygotowującej). - Sprawdź, czy na urządzeniu jest włączony GPS przy użyciu funkcji
isProviderEnabled(LocationManager.GPS_PROVIDER)
. W razie potrzeby użytkownik poprosi o otworzenie ustawień lokalizacji. - W wymagających przypadkach, gdy otrzymywanie danych o lokalizacji z krótkim czasem oczekiwania jest bardzo ważne, rozważ zintegrowanie dostawcy uśrednionej lokalizacji i wykorzystanie jego danych jako początkowej poprawki lokalizacji. Jeśli dostępne są bardziej stabilne informacje o lokalizacji, użyj ich zamiast FLP.
- Aplikacja zachowuje
- Jeśli aplikacja wymaga przesłania danych, wszelkie wywołania sieciowe do przesyłania danych są odroczone do czasu zakończenia ćwiczenia. W przeciwnym razie podczas ćwiczenia aplikacja będzie oszczędnie wykonywać wszystkie niezbędne połączenia sieciowe.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Aktualizacje danych pasywnych
- Usługi zdrowotne na Wear OS
- Pierwsze kroki z kafelkami