Usługi związane ze zdrowiem zapewniają obsługę aplikacji do ćwiczeń za pomocą ExerciseClient
.
Dzięki ExerciseClient
aplikacja może kontrolować, kiedy ćwiczenie jest w toku, dodawać cele ćwiczeń i otrzymywać aktualizacje dotyczące stanu ćwiczenia, zdarzeń związanych z ćwiczeniami lub innych danych. Więcej informacji znajdziesz na pełnej liście rodzajów ćwiczeń
obsługiwanych przez Usługi dotyczące zdrowia.
Zobacz przykładowe ćwiczenie w GitHubie.
Dodawanie zależności
Aby dodać zależność od Usług zdrowotnych, musisz dodać do projektu repozytorium Google Maven. Więcej informacji znajdziesz w repozytorium Maven Google.
Następnie w pliku build.gradle
na poziomie modułu dodaj tę zależność:
Groovy
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha05" }
Kotlin
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha05") }
Struktura aplikacji
Podczas tworzenia aplikacji do ćwiczeń z użyciem Usług zdrowotnych używaj tej struktury:
- Ekrany i nawigacja powinny znajdować się 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.
- Przechowuj dane w Room i używaj WorkManager do przesyłania danych.
Podczas przygotowywania się do treningu i w jego trakcie aktywność może zostać przerwana 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ś na wierzchu Twojej aktywności lub ekran może się wyłączyć po okresie bezczynności.
Używaj stale działającego ForegroundService
w połączeniu z ExerciseClient
, aby zapewnić prawidłowe działanie przez cały trening.
Użycie ForegroundService
umożliwia korzystanie z interfejsu Ongoing Activity API do wyświetlania wskaźnika na tarczach zegarka, dzięki czemu użytkownik może szybko wrócić do treningu.
Konieczne jest prawidłowe żądanie danych o lokalizacji w usłudze działającej na pierwszym planie. W pliku manifestu określ niezbędne typy usług na pierwszym planie i 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żyj
AmbientLifecycleObserver
w przypadku aktywności przed treningiem, która zawiera wywołanie prepareExercise()
, oraz
w przypadku aktywności podczas treningu. Nie aktualizuj jednak wyświetlacza podczas treningu w trybie otoczenia: usługi Zdrowie grupują dane treningu, gdy ekran urządzenia jest w trybie otoczenia, aby oszczędzać energię, więc wyświetlane informacje mogą nie być aktualne. Podczas treningów wyświetlaj dane, które są przydatne dla użytkownika, pokazując aktualne informacje lub pusty ekran.
Sprawdzanie możliwości
Każdy ExerciseType
obsługuje określone typy danych dotyczące danych i celów związanych z aktywnością fizyczną. Sprawdź te możliwości przy uruchamianiu, ponieważ 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, np. automatycznego wstrzymywania. Dodatkowo możliwości urządzenia mogą się z czasem zmieniać, np. po aktualizacji oprogramowania.
Podczas uruchamiania aplikacji wysyłaj zapytania o możliwości urządzenia oraz przechowuj i przetwarzaj te informacje:
- ćwiczenia obsługiwane przez platformę;
- funkcje obsługiwane w przypadku poszczególnych ćwiczeń;
- Typy danych obsługiwane w przypadku poszczególnych ćwiczeń.
- uprawnienia wymagane w przypadku każdego z tych typów danych;
Używaj urządzenia ExerciseCapabilities.getExerciseTypeCapabilities()
z wybranym typem ćwiczeń, aby sprawdzić, o jakie dane możesz poprosić, jakie cele ćwiczeń możesz skonfigurować i jakie inne funkcje są dostępne w przypadku tego typu. Pokazuje to poniższy przykład:
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óconej liście ExerciseTypeCapabilities
,
supportedDataTypes
znajdują się typy danych, o które możesz poprosić. Różni się to w zależności od urządzenia, więc uważaj, aby nie prosić o DataType
, które nie jest obsługiwane. W przeciwnym razie Twoja prośba może się nie powieść.
W polach supportedGoals
i supportedMilestones
określ, czy ćwiczenie może obsługiwać cel ćwiczenia, który chcesz utworzyć.
Jeśli aplikacja umożliwia użytkownikowi korzystanie z automatycznego wstrzymywania, musisz sprawdzić, czy ta funkcja jest obsługiwana przez urządzenie, używając supportsAutoPauseAndResume
.
ExerciseClient
odrzuca żądania, które nie są obsługiwane na urządzeniu.
W tym przykładzie sprawdzamy obsługę typu danych HEART_RATE_BPM
, funkcję celu STEPS_TOTAL
i 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
Rejestrowanie aktualizacji stanu ćwiczeń
Aktualizacje ćwiczeń są dostarczane do słuchacza. Aplikacja może zarejestrować tylko jednego odbiorcę naraz. Skonfiguruj odbiornik przed rozpoczęciem treningu, jak pokazano w poniższym przykładzie. Odbiorca otrzymuje tylko aktualizacje dotyczące ćwiczeń, których właścicielem jest 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ądzanie czasem trwania ćwiczenia
Usługi związane ze zdrowiem obsługują co najwyżej 1 ćwiczenie naraz we wszystkich aplikacjach na urządzeniu. Jeśli śledzone jest ćwiczenie, a inna aplikacja zacznie śledzić nowe ćwiczenie, pierwsze ćwiczenie zostanie zakończone.
Zanim zaczniesz ćwiczyć, wykonaj te czynności:
- Sprawdź, czy ćwiczenie jest już śledzone, i odpowiednio zareaguj. Na przykład poproś użytkownika o potwierdzenie przed zastąpieniem poprzedniego ćwiczenia i rozpoczęciem śledzenia nowego.
Poniższy przykład pokazuje, jak sprawdzić, czy istnieje ćwiczenie z wywołaniem 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
Podczas korzystania z ExerciseClient
upewnij się, że Twoja aplikacja prosi o niezbędne uprawnienia i je utrzymuje.
Jeśli Twoja aplikacja korzysta z danych LOCATION
, upewnij się, że żąda odpowiednich uprawnień i je utrzymuje.
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 Prośby o przyznanie uprawnień aplikacji. Usługi związane ze zdrowiem odrzucają żądanie, jeśli niezbędne uprawnienia nie zostały jeszcze przyznane.
W przypadku danych o lokalizacji wykonaj te dodatkowe czynności:
- Sprawdź, czy GPS jest włączony na urządzeniu za pomocą
isProviderEnabled(LocationManager.GPS_PROVIDER)
. W razie potrzeby poproś użytkownika o otwarcie ustawień lokalizacji. - Upewnij się, że podczas całego treningu utrzymujesz
ForegroundService
z odpowiednimforegroundServiceType
.
Przygotowanie do treningu
Niektóre czujniki, np. GPS lub czujnik tętna, mogą potrzebować trochę czasu na rozgrzanie się, a użytkownik może chcieć zobaczyć dane przed rozpoczęciem treningu. Opcjonalna metoda
prepareExerciseAsync()
umożliwia rozgrzanie tych czujników i otrzymywanie danych bez włączania timera treningu. Ten czas przygotowania nie ma wpływu na activeDuration
.
Zanim zadzwonisz pod numer prepareExerciseAsync()
, sprawdź te kwestie:
Sprawdź ustawienie lokalizacji na poziomie platformy. 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ś go o włączenie tej funkcji, jeśli jest ona wymagana przez Twoją aplikację.
Sprawdź, czy aplikacja ma uprawnienia do czujników na ciele (API na poziomie 35 lub niższym) lub do pomiaru tętna (API na poziomie 36 lub wyższym), rozpoznawania aktywności i dokładnej lokalizacji. W przypadku brakujących uprawnień poproś użytkownika o przyznanie uprawnień w czasie działania, podając odpowiedni kontekst. Jeśli użytkownik nie przyzna określonego uprawnienia, usuń z wywołania funkcji
prepareExerciseAsync()
typy danych powiązane z tym uprawnieniem. Jeśli nie przyznano uprawnień do czujników na ciele (tętno na poziomie interfejsu API 36 lub wyższym) ani uprawnień do lokalizacji, nie wywołuj funkcjiprepareExerciseAsync()
, ponieważ wywołanie prepare służy do uzyskania stabilnego tętna lub stałej lokalizacji GPS przed rozpoczęciem ćwiczenia. Aplikacja nadal może uzyskiwać dane o dystansie, tempie, prędkości i innych wskaźnikach, które nie wymagają tych uprawnień.
Aby sprawdzić, czy wywołanie funkcji prepareExerciseAsync()
może się powieść:
- Użyj
AmbientLifecycleObserver
w przypadku aktywności przed treningiem, która zawiera wywołanie przygotowania. - Wywołaj
prepareExerciseAsync()
z usługi działającej na pierwszym planie. Jeśli nie jest ona częścią usługi i jest powiązana z cyklem życia aktywności, przygotowanie czujnika może zostać niepotrzebnie zakończone. - Wywołaj
endExercise()
, aby wyłączyć czujniki i zmniejszyć zużycie energii, jeśli użytkownik opuści aktywność przed treningiem.
Poniższy przykład pokazuje, jak wywołać funkcję prepareExerciseAsync()
:
val warmUpConfig = WarmUpConfig(
ExerciseType.RUNNING,
setOf(
DataType.HEART_RATE_BPM,
DataType.LOCATION
)
)
// Only necessary to call prepareExerciseAsync if body sensor (API level 35
// or lower), heart rate (API level 36+), or location permissions are given.
exerciseClient.prepareExerciseAsync(warmUpConfig).await()
// Data and availability updates are delivered to the registered listener.
Gdy aplikacja jest w stanie PREPARING
, aktualizacje dostępności czujników są dostarczane w stanie ExerciseUpdateCallback
przez onAvailabilityChanged()
.
Te informacje mogą być następnie wyświetlane użytkownikowi, aby mógł zdecydować, czy rozpocząć trening.
Rozpocznij trening
Gdy chcesz rozpocząć ćwiczenie, utwórz ExerciseConfig
, aby skonfigurować typ ćwiczenia, typy danych, dla których chcesz otrzymywać dane, oraz cele lub kamienie milowe ćwiczenia.
Cele ćwiczeń składają się z DataType
i warunku. Cele ćwiczeń to jednorazowe cele, które są wywoływane po spełnieniu warunku, np. gdy użytkownik przebiegnie określony dystans. Możesz też ustawić kamień milowy związany z ćwiczeniami. Osiągnięcia związane z ćwiczeniami mogą być wywoływane wielokrotnie, np. za każdym razem, gdy użytkownik przebiegnie określony punkt za wyznaczonym dystansem.
Poniższy przykład pokazuje, jak utworzyć po jednym 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ż oznaczać okrążenia we wszystkich ćwiczeniach. Usługi dotyczące zdrowia udostępniają ExerciseLapSummary
ze wskaźnikami zagregowanymi w okresie okrążenia.
W poprzednim przykładzie pokazano użycie wartości isGpsEnabled
, która musi być prawdziwa, gdy wysyłane jest żądanie danych o lokalizacji. Korzystanie z GPS może jednak pomóc w określaniu innych danych. Jeśli ExerciseConfig
określa dystans jako DataType
,
domyślnie do szacowania dystansu używane są kroki. Opcjonalnie możesz włączyć GPS, aby do szacowania odległości używać informacji o lokalizacji.
Wstrzymywanie, wznawianie i kończenie treningu
Treningi możesz wstrzymywać, wznawiać i kończyć za pomocą odpowiedniej metody, np. pauseExerciseAsync()
lub endExerciseAsync()
.
Użyj stanu z ExerciseUpdate
jako źródła informacji. Trening nie jest uznawany za wstrzymany, gdy zwracana jest wartość wywołania pauseExerciseAsync()
, ale gdy ten stan jest odzwierciedlony w wiadomości ExerciseUpdate
. Jest to szczególnie ważne w przypadku stanów interfejsu. Jeśli użytkownik naciśnie przycisk wstrzymania, wyłącz go i wywołaj funkcję pauseExerciseAsync()
w usługach zdrowotnych. Poczekaj, aż Usługi zdrowotne osiągną stan wstrzymania, korzystając z ExerciseUpdate.exerciseStateInfo.state
, a następnie przełącz przycisk, aby wznowić działanie. Dzieje się tak, ponieważ aktualizacje stanu Usług zdrowotnych mogą być dostarczane dłużej niż naciśnięcie przycisku. Jeśli powiążesz wszystkie zmiany interfejsu z naciśnięciami przycisków, interfejs może się rozsynchronizować ze stanem Usług zdrowotnych.
Pamiętaj o tym w tych sytuacjach:
- Automatyczne wstrzymywanie jest włączone: trening może się wstrzymać lub rozpocząć bez interakcji użytkownika.
- Inna aplikacja rozpoczyna trening: trening może zostać zakończony bez interakcji użytkownika.
Jeśli trening w aplikacji zostanie zakończony przez inną aplikację, musi ona prawidłowo obsłużyć to zakończenie:
- Zapisz stan częściowego treningu, aby nie utracić postępów użytkownika.
- Usuń ikonę trwającej aktywności i wyślij użytkownikowi powiadomienie z informacją, że trening został zakończony przez inną aplikację.
Obsługuj też sytuację, w której uprawnienia zostaną cofnięte podczas trwającego ćwiczenia. Jest on wysyłany w stanie isEnded
z wartością ExerciseEndReason
AUTO_END_PERMISSION_LOST
. W tym przypadku postępuj podobnie jak w przypadku zakończenia: zapisz częściowy stan, usuń ikonę trwającej aktywności i wyślij użytkownikowi powiadomienie o tym, co się stało.
Poniższy przykład pokazuje, jak prawidłowo sprawdzić, czy nastąpiło zakończenie:
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ądzanie czasem aktywności
Podczas ćwiczeń aplikacja może wyświetlać czas trwania aktywności. Aplikacja, Usługi zdrowotne i mikrokontroler urządzenia (MCU) – energooszczędny procesor odpowiedzialny za śledzenie ćwiczeń – muszą być zsynchronizowane i mieć ten sam bieżący czas trwania aktywności. Aby ułatwić zarządzanie tym procesem, Usługi zdrowotne wysyłają ActiveDurationCheckpoint
, który stanowi punkt odniesienia, od którego aplikacja może rozpocząć odliczanie czasu.
Ponieważ czas aktywności jest wysyłany z mikrokontrolera i może minąć trochę czasu, zanim dotrze do aplikacji, obiekt ActiveDurationCheckpoint
zawiera 2 właściwości:
activeDuration
: czas trwania ćwiczeniatime
: kiedy obliczono czas aktywności.
Dlatego w aplikacji aktywny czas trwania ćwiczenia można obliczyć na podstawie wartości ActiveDurationCheckpoint
za pomocą tego równania:
(now() - checkpoint.time) + checkpoint.activeDuration
Uwzględnia to niewielką różnicę między czasem trwania aktywności obliczanym na mikrokontrolerze a czasem trwania aktywności docierającym do aplikacji. Można go użyć do zainicjowania chronometru w aplikacji i zapewnienia, że timer aplikacji jest idealnie zsynchronizowany z czasem w Usługach zdrowotnych i na mikrokontrolerze.
Jeśli ćwiczenie zostanie wstrzymane, aplikacja poczeka z ponownym uruchomieniem timera w interfejsie, aż obliczony czas przekroczy czas wyświetlany w interfejsie.
Dzieje się tak, ponieważ sygnał wstrzymania dociera do usług zdrowotnych i mikrokontrolera z niewielkim opóźnieniem. Jeśli na przykład aplikacja jest wstrzymana w momencie t=10 sekund, Usługi zdrowotne mogą nie przekazać aplikacji aktualizacji PAUSED
do momentu t=10, 2 sekundy.
Praca z danymi z interfejsu ExerciseClient
Dane dotyczące typów danych, dla których zarejestrowana jest Twoja aplikacja, są dostarczane w wiadomościach ExerciseUpdate
.
Procesor dostarcza wiadomości tylko wtedy, gdy jest aktywny lub gdy osiągnięty zostanie maksymalny okres raportowania, np. co 150 sekund. Nie polegaj na ExerciseUpdate
częstotliwości, aby przesuwać chronometr za pomocą activeDuration
. Przykład implementacji niezależnego chronometru znajdziesz w przykładowym ćwiczeniu w GitHubie.
Gdy użytkownik rozpocznie trening, ExerciseUpdate
wiadomości mogą być dostarczane często, np. co sekundę. Gdy użytkownik rozpocznie trening, ekran może się wyłączyć. Usługi zdrowotne mogą wtedy rzadziej dostarczać dane, ale nadal będą próbkowane z tą samą częstotliwością, aby uniknąć wybudzania głównego procesora. Gdy użytkownik patrzy na ekran, wszystkie dane, które są w trakcie przetwarzania wsadowego, są natychmiast dostarczane do aplikacji.
Kontrolowanie szybkości przetwarzania zbiorczego
W niektórych przypadkach 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 zachowania związanego z grupowaniem, aby częściej otrzymywać dane.
Aby skonfigurować szybkość przetwarzania wsadowego, wykonaj te czynności:
Sprawdź, czy urządzenie obsługuje daną
BatchingMode
definicję:// 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
ma używać konkretnego elementuBatchingMode
, jak pokazano 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, zamiast utrzymywać określone zachowanie grupowania przez cały czas trwania treningu:val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS) exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
Aby wyczyścić dostosowany zbiór
BatchingMode
i przywrócić domyślne działanie, przekaż pusty zbiór do funkcjiexerciseClient.overrideBatchingModesForActiveExercise()
.
Sygnatury czasowe
Punkt w czasie każdego punktu danych reprezentuje czas od uruchomienia urządzenia. Aby przekonwertować go na sygnaturę czasową:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Tej wartości można następnie użyć 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.
Jest to reprezentowane przez właściwość accuracy
.
Klasy HrAccuracy
i LocationAccuracy
można wypełniać odpowiednio typami danych HEART_RATE_BPM
i LOCATION
. Jeśli jest dostępna, użyj właściwości
accuracy
, aby określić, czy każdy punkt danych ma wystarczającą dokładność dla Twojej aplikacji.
Przechowywanie i przesyłanie danych
Użyj Room, aby utrwalać dane dostarczane przez Health Services. Przesyłanie danych następuje na końcu ćwiczenia za pomocą mechanizmu takiego jak Work Manager. Pomaga to sprawdzić, czy wywołania sieciowe służące do przesyłania danych są odraczane do czasu zakończenia ćwiczenia, co minimalizuje zużycie energii podczas ćwiczenia i upraszcza pracę.
Lista kontrolna integracji
Przed opublikowaniem aplikacji korzystającej z ExerciseClient
Usług zdrowotnych zapoznaj się z tą listą kontrolną, aby sprawdzić, czy w przypadku użytkowników nie występują typowe problemy. Upewnij się, że:
- Aplikacja sprawdza możliwości rodzaju ćwiczenia i urządzenia za każdym razem, gdy jest uruchamiana. Dzięki temu możesz wykryć, kiedy dane urządzenie lub ćwiczenie nie obsługuje jednego z rodzajów danych, których potrzebuje Twoja aplikacja.
- Musisz poprosić o niezbędne uprawnienia i je zachować, a także określić je w pliku manifestu. Przed wywołaniem funkcji
prepareExerciseAsync()
aplikacja sprawdza, czy przyznano uprawnienia w czasie działania. - Aplikacja używa
getCurrentExerciseInfoAsync()
do obsługi przypadków, w których:- Ćwiczenie jest już śledzone, a aplikacja zastępuje poprzednie ćwiczenie.
- Inna aplikacja zakończyła ćwiczenie. Może się to zdarzyć, gdy użytkownik ponownie otworzy aplikację i zobaczy komunikat z informacją, że ćwiczenie zostało przerwane, ponieważ inna aplikacja przejęła kontrolę.
- Jeśli używasz danych
LOCATION
:- Aplikacja utrzymuje
ForegroundService
z odpowiednimforegroundServiceType
przez cały czas trwania ćwiczenia (w tym podczas przygotowania do połączenia). - Sprawdza, czy na urządzeniu jest włączony GPS, i w razie potrzeby wyświetla użytkownikowi prośbę o otwarcie ustawień lokalizacji.
isProviderEnabled(LocationManager.GPS_PROVIDER)
- W przypadku wymagających zastosowań, w których otrzymywanie danych o lokalizacji z niskim opóźnieniem ma duże znaczenie, rozważ zintegrowanie usługi lokalizacji zintegrowanej (FLP) i używanie jej danych jako początkowego określenia lokalizacji. Gdy Usługi zdrowotne udostępnią bardziej stabilne informacje o lokalizacji, używaj ich zamiast FLP.
- Aplikacja utrzymuje
- Jeśli Twoja aplikacja wymaga przesyłania danych, wszystkie wywołania sieciowe służące do przesyłania danych są odraczane do czasu zakończenia ćwiczenia. W przeciwnym razie aplikacja będzie w trakcie ćwiczenia oszczędnie wykonywać niezbędne wywołania sieciowe.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony.
- Aktualizacje danych pasywnych
- Usługi związane ze zdrowiem na Wear OS
- Pierwsze kroki z kafelkami