Passive Datenupdates eignen sich für Apps, die Gesundheitsdienste überwachen müssen im Hintergrund ausgeführt werden. Sie sind für Anwendungsfälle gedacht, die Stunden, Tage oder noch länger. Wenn Sie Gesundheitsdaten speichern oder verarbeiten müssen, läuft und der Nutzer nicht explizit an einer Übung teilnimmt, verwende Der passive Client des Health Service.
Beispiele für die passive Datennutzung finden Sie auf der Passive Daten und Passive Ziele 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 in der Datei build.gradle
auf Modulebene die folgende Abhängigkeit hinzu:
Cool
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha03" }
Kotlin
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha03") }
Funktionen prüfen
Bevor Sie sich für Datenupdates registrieren, prüfen Sie, ob das Gerät den Typ die Ihre App benötigt. Mit der Überprüfung der Funktionen können Sie Funktionen ändern oder die Benutzeroberfläche Ihrer App ändern, um Funktionen zu kompensieren, nicht verfügbar.
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
}
Für passive Daten registrieren
Sie können passive Daten über einen Dienst, einen Callback oder beides empfangen. A kann Ihre App Daten im Hintergrund empfangen, wenn kein Teil Ihres App im Vordergrund zu sehen ist. Wenn Sie Daten im Hintergrund empfangen, in Batches bereitgestellt. Der Callback empfängt Daten etwas schneller, während die App ausgeführt wird und der Callback erfolgreich benachrichtigt wird.
Unabhängig von der verwendeten Methode müssen Sie zuerst ein PassiveListenerConfig
erstellen.
bestimmt, welche Datentypen empfangen werden sollen, wie im folgenden Beispiel gezeigt:
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDataTypes(setOf(DataType.HEART_RATE_BPM))
.build()
Um Daten über einen Callback zu empfangen, definieren und registrieren Sie den Callback, wie in im folgenden Beispiel:
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()
Die Verwendung eines Dienstes ist ähnlich, aber anstatt eine Klasse zu erstellen, die aus
PassiveListenerCallback
, abgeleitet von PassiveListenerService
, wie in
im folgenden Beispiel:
class PassiveDataService : PassiveListenerService() {
override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
// TODO: Do something with dataPoints
}
}
passiveMonitoringClient.setPassiveListenerServiceAsync(
PassiveDataService::class.java,
passiveListenerConfig
)
Als Nächstes deklarieren Sie den Dienst in der Datei AndroidManifest.xml
. Gesundheitszustand erforderlich
Berechtigung „Dienste“, mit der sichergestellt wird, dass nur Gesundheitsdienste eine Bindung herstellen können
an den Dienst:
<service android:name=".PassiveDataService"
android:permission="com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING"
android:exported="true" />
Zeit interpretieren
Die Daten, die du von Health Services erhältst, werden in Batches zusammengefasst, sodass du Daten empfangen kannst unterschiedlichen Typen oder mehrere Datenpunkte desselben Typs im selben zu erstellen. Verwenden Sie anstelle der Uhrzeit die in diesen Objekten enthaltenen Zeitstempel die von Ihrer App empfangen wurden, um die richtige Reihenfolge der Ereignisse zu bestimmen.
Um Zeitstempel für jede DataPoint
zu erhalten, berechnen Sie zuerst den Bootzeitstempel.
Dies wird im folgenden Beispiel gezeigt:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Dieser Wert kann dann an
getStartInstant()
oder
getEndInstant()
Registrierungen nach dem Booten wiederherstellen
Passive Datenregistrierungen gehen bei Neustarts nicht verloren. Um Daten zu empfangen, nachdem
dein Gerät neu gestartet wurde, erstelle deine Registrierungen mit einem BroadcastReceiver
neu, der
auf das Ereignis
ACTION_BOOT_COMPLETED
Systemnachricht an.
Versuchen Sie nicht, die Registrierungen im Empfänger direkt wiederherzustellen. Stattdessen
Sie können diese Funktion an einen WorkManager
-Worker delegieren. Wenn der Parameter
Gerät gestartet wird, kann es 10 Sekunden oder länger dauern, bis
eine passive Datenregistrierungsanfrage bestätigen. Dies könnte die
zulässige Ausführungszeit einer BroadcastReceiver
. Im Gegensatz dazu: WorkManager
Arbeiter:innen haben:
Ausführungslimit von 10 Minuten.
Das folgende Snippet zeigt, wie ein BroadcastReceiver
aussehen könnte:
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()
}
}
Damit das System diesen Code beim Hochfahren des Geräts ausführt,
zwei Änderungen an der Datei AndroidManifest.xml
.
Fügen Sie zuerst die folgende Berechtigung als untergeordnetes Element von <manifest>
hinzu:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Fügen Sie dann den folgenden Empfänger-Intent-Filter als untergeordnetes Element von <application>
hinzu:
<receiver
android:name=".StartupReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Aktivitätsstatus
Der passive Client kann auch allgemeine Informationen zum Nutzerstatus liefern, wie ob der Nutzer schläft. So erhalten Sie Updates:
- Fordern Sie die Berechtigung
ACTIVITY_RECOGNITION
an. - Rufen Sie
setShouldUserActivityInfoBeRequested(true)
in derPassiveListenerConfig
-Builder.
onUserActivityInfoReceived()
-Methode in Ihrem Callback oder Dienst überschreiben
und verwenden den zurückgegebenen UserActivityInfo
, wie im folgenden Beispiel gezeigt:
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) {
// ...
}
}
Passive Ziele
Sie können einen passiven Client so konfigurieren, dass die App über passive Ziele benachrichtigt wird erreicht werden, z. B. wenn der Nutzer 10.000 Schritte an einem Tag ausführt.
Erstellen Sie dazu ein Zielvorhaben wie im folgenden Beispiel:
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)
}
Fügen Sie dieses Zielvorhaben wie unten gezeigt Ihrem PassiveListenerConfig
hinzu
Beispiel:
val passiveListenerConfig = PassiveListenerConfig.builder()
.setDailyGoals(setOf(dailyStepsGoal))
.build()
onGoalCompleted()
-Methode in Ihrem Callback oder Dienst überschreiben
und verwenden den zurückgegebenen PassiveGoal
, wie im folgenden Beispiel gezeigt:
override fun onGoalCompleted(goal: PassiveGoal) {
when (goal.dataTypeCondition.dataType) {
DataType.STEPS_DAILY -> {
// ...
}
}
}
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Aktive Daten und Trainings
- Erste Schritte mit Ansichten
- Ladebildschirm hinzufügen