Pasywne aktualizacje danych są odpowiednie dla aplikacji, które muszą w tle monitorować dane usług medycznych. Są przeznaczone do stosowania w przypadkach obejmujących godziny, dni, a nawet dłużej. Jeśli musisz przechowywać lub przetwarzać dane dotyczące zdrowia, gdy Twoja aplikacja nie jest uruchomiona, a użytkownik nie jest wyraźnie zaangażowany w ćwiczenie, użyj pasywnego klienta usługi Health Service.
Przykłady pasywnego wykorzystania danych znajdziesz w przykładach dotyczących danych pasywnych i celów pasywnych w 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.
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") }
Sprawdź możliwości
Zanim zarejestrujesz się w celu aktualizacji danych, sprawdź, czy urządzenie może dostarczać typ danych, których potrzebuje Twoja aplikacja. Sprawdzanie możliwości pozwala włączać i wyłączać niektóre funkcje oraz modyfikować interfejs aplikacji, aby zrekompensować funkcje, które są niedostępne.
val healthClient = HealthServices.getClient(this /*context*/)
val passiveMonitoringClient = healthClient.passiveMonitoringClient
lifecycleScope.launchWhenCreated {
val capabilities = passiveMonitoringClient.capabilities.await()
// Supported types for passive data collection
supportsHeartRate =
DataType.HEART_RATE_BPM in capabilities.supportedDataTypesPassiveMonitoring
// Supported types for PassiveGoals
supportsStepsGoal =
DataType.STEPS_DAILY in capabilities.supportedDataTypesPassiveGoals
}
Zarejestruj dla danych pasywnych
Dane pasywne możesz otrzymywać za pomocą usługi, wywołania zwrotnego lub obu tych metod. Usługa umożliwia aplikacji odbieranie danych w tle, gdy żadna jej część nie jest widoczna na pierwszym planie. Gdy odbierasz dane w tle, są one wysyłane partiami. Wywołanie zwrotne odbiera dane z nieco szybszą szybkością, ale tylko wtedy, gdy aplikacja jest uruchomiona, a wywołanie zwrotne jest powiadamiane.
Niezależnie od wybranej metody utwórz najpierw element PassiveListenerConfig
określający typy danych do otrzymywania, jak w tym przykładzie:
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDataTypes(setOf(DataType.HEART_RATE_BPM))
.build()
Aby odbierać dane za pomocą wywołania zwrotnego, zdefiniuj i zarejestruj wywołanie zwrotne, tak jak w tym przykładzie:
val passiveListenerCallback: PassiveListenerCallback = object : PassiveListenerCallback {
override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
// TODO: Do something with dataPoints
}
}
passiveMonitoringClient.setPassiveListenerCallback(
passiveListenerConfig,
passiveListenerCallback
)
// To remove the listener
passiveMonitoringClient.clearPassiveListenerCallbackAsync()
Korzystanie z usługi jest podobne, ale zamiast tworzyć klasę generowaną na podstawie PassiveListenerCallback
, pobierz dane z elementu PassiveListenerService
, jak pokazano w tym przykładzie:
class PassiveDataService : PassiveListenerService() {
override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
// TODO: Do something with dataPoints
}
}
passiveMonitoringClient.setPassiveListenerServiceAsync(
PassiveDataService::class.java,
passiveListenerConfig
)
Następnie zadeklaruj usługę w pliku AndroidManifest.xml
. Wymagaj uprawnienia dotyczącego usług medycznych, które daje pewność, że z usługą mogą być powiązane tylko te usługi:
<service android:name=".PassiveDataService"
android:permission="com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING"
android:exported="true" />
Zinterpretuj czas
Dane otrzymywane z usług zdrowotnych są grupowane, możesz więc otrzymywać w jednej grupie punkty danych różnego typu lub wiele punktów danych tego samego typu. Do określenia prawidłowej kolejności zdarzeń używaj sygnatur czasowych w tych obiektach, a nie czasu ich otrzymania przez aplikację.
Aby uzyskać sygnatury czasowe dla każdego elementu DataPoint
, najpierw oblicz sygnaturę czasową uruchamiania, jak pokazano w tym przykładzie:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Wartość tę można przekazać do funkcji getStartInstant()
lub getEndInstant()
.
Przywróć rejestracje po uruchomieniu
Pasywne rejestracje danych nie są zachowywane po ponownym uruchomieniu. Aby odebrać dane po ponownym uruchomieniu urządzenia, utwórz rejestracje jeszcze raz za pomocą BroadcastReceiver
, który nasłuchuje transmisji systemowej ACTION_BOOT_COMPLETED
.
Nie próbuj bezpośrednio przywrócić rejestracji w odbiorniku. Zamiast tego przekaż tę funkcję instancji roboczej WorkManager
. Podczas uruchamiania urządzenia usługi zdrowotne mogą potrzebować co najmniej 10 sekund na potwierdzenie pasywnego żądania rejestracji danych. Może to spowodować przekroczenie dozwolonego czasu wykonywania instrukcji BroadcastReceiver
. Natomiast w przypadku WorkManager
instancji roboczych limit wykonywania wynosi 10 minut.
Ten fragment kodu pokazuje, jak może wyglądać element BroadcastReceiver
:
class StartupReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != Intent.ACTION_BOOT_COMPLETED) return
// TODO: Check permissions first
WorkManager.getInstance(context).enqueue(
OneTimeWorkRequestBuilder<RegisterForPassiveDataWorker>().build()
)
}
}
class RegisterForPassiveDataWorker(
private val appContext: Context,
workerParams: WorkerParameters
) : Worker(appContext, workerParams) {
override fun doWork(): Result {
runBlocking {
HealthServices.getClient(appContext)
.passiveMonitoringClient
.setPassiveListenerCallback(...)
}
return Result.success()
}
}
Aby system mógł wykonywać ten kod po uruchomieniu urządzenia, wprowadź 2 zmiany w pliku AndroidManifest.xml
.
Najpierw dodaj to uprawnienie jako uprawnienia podrzędne uprawnień <manifest>
:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Następnie dodaj ten filtr intencji odbiorcy jako element podrzędny elementu <application>
:
<receiver
android:name=".StartupReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Stan aktywności
Klient pasywny może też udostępniać ogólne informacje o stanie użytkownika, np. o tym, czy użytkownik uśpił. Aby otrzymywać te powiadomienia, wykonaj te czynności:
- Poproś o uprawnienie
ACTIVITY_RECOGNITION
. - Wywołaj
setShouldUserActivityInfoBeRequested(true)
w kreatorzePassiveListenerConfig
.
Zastąp metodę onUserActivityInfoReceived()
w wywołaniu zwrotnym lub usłudze i użyj zwróconego UserActivityInfo
, jak pokazano w tym przykładzie:
override fun onUserActivityInfoReceived(info: UserActivityInfo) {
val stateChangeTime: Instant = info.stateChangeTime // may be in the past!
val userActivityState: UserActivityState = info.userActivityState
if (userActivityState == UserActivityState.USER_ACTIVITY_ASLEEP) {
// ...
}
}
Cele pasywne
Możesz skonfigurować klienta pasywnego, aby powiadamiał aplikację o osiągnięciu celów pasywnych,np. gdy użytkownik zrealizuje 10 tys. kroków w ciągu dnia.
W tym celu utwórz cel w następujący sposób:
val dailyStepsGoal by lazy {
val condition = DataTypeCondition(
dataType = DataType.STEPS_DAILY,
threshold = 10_000, // Trigger every 10000 steps
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
)
PassiveGoal(condition)
}
Dodaj ten cel do celu (PassiveListenerConfig
), jak pokazano w tym przykładzie:
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDailyGoals(setOf(dailyStepsGoal))
.build()
Zastąp metodę onGoalCompleted()
w wywołaniu zwrotnym lub usłudze i użyj zwróconego PassiveGoal
, jak pokazano w tym przykładzie:
override fun onGoalCompleted(goal: PassiveGoal) {
when (goal.dataTypeCondition.dataType) {
DataType.STEPS_DAILY -> {
// ...
}
}
}
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Aktywne dane i ćwiczenia
- Pierwsze kroki z kafelkami
- Dodawanie ekranu powitalnego