Wenn Sie die Data Layer API aufrufen, können Sie den Parameter Status des Aufrufs nach Abschluss des Aufrufs. Sie können auch auf Datenereignisse warten, die sich aus Datenänderungen ergeben, die Ihre App irgendwo im Wear OS by Google-Netzwerk.
Ein Beispiel für die effektive Arbeit mit dem Data Layer API finden Sie in der <ph type="x-smartling-placeholder"></ph> Android DataLayer Sample App.
Auf Status von Datenschichtaufrufen warten
Aufrufe an die Data Layer API, z. B. Aufrufe über die putDataItem
der Methode
DataClient
-Klasse – manchmal wird ein
Task<ResultType>
-Objekt. Sobald das Task
-Objekt
erstellt wurde, ist der Vorgang
im Hintergrund in die Warteschlange gestellt. Wenn Sie danach nichts weiter tun, wird der Vorgang
wird schließlich im Hintergrund abgeschlossen.
Üblicherweise sollten Sie jedoch
das Ergebnis nach Abschluss des Vorgangs, sodass das Task
-Objekt
warten Sie auf den Ergebnisstatus, entweder asynchron oder synchron.
Asynchrone Aufrufe
Wenn Ihr Code im Haupt-UI-Thread ausgeführt wird, führen Sie keine blockierenden Aufrufe an den
Data Layer API. Aufrufe durch Hinzufügen einer Callback-Methode asynchron ausführen
an das Task
-Objekt, das ausgelöst wird, wenn der Vorgang abgeschlossen ist:
Kotlin
// Using Kotlin function references task.addOnSuccessListener(::handleDataItem) task.addOnFailureListener(::handleDataItemError) task.addOnCompleteListener(::handleTaskComplete) ... fun handleDataItem(dataItem: DataItem) { ... } fun handleDataItemError(exception: Exception) { ... } fun handleTaskComplete(task: Task<DataItem>) { ... }
Java
// Using Java 8 Lambdas. task.addOnSuccessListener(dataItem -> handleDataItem(dataItem)); task.addOnFailureListener(exception -> handleDataItemError(exception)); task.addOnCompleteListener(task -> handleTaskComplete(task));
Siehe Task-API für andere Möglichkeiten, einschließlich Verkettung der Ausführung von verschiedene Aufgaben zu erledigen.
Synchrone Aufrufe
Wenn Ihr Code in einem separaten Handler-Thread in einem Hintergrunddienst ausgeführt wird,
z. B. in einem
WearableListenerService
,
können Sie die Anrufe blockieren. In diesem Fall können Sie Tasks.await()
in der Task
, das bis zum Abschluss der Anfrage blockiert und eine
Result
-Objekt. Dies wird im folgenden Beispiel gezeigt.
Hinweis:Rufen Sie diese Nachricht nicht auf, während Sie sich im Hauptthread befinden.
Kotlin
try { Tasks.await(dataItemTask).apply { Log.d(TAG, "Data item set: $uri") } } catch (e: ExecutionException) { ... } catch (e: InterruptedException) { ... }
Java
try { DataItem item = Tasks.await(dataItemTask); Log.d(TAG, "Data item set: " + item.getUri()); } catch (ExecutionException | InterruptedException e) { ... }
Auf Datenschichtereignisse warten
Da die Datenschicht Daten synchronisiert und über das Handheld und Wearables müssen Sie in der Regel auf wichtige Ereignisse wie Datenelemente, die erstellt werden und empfangene Nachrichten.
Es gibt zwei Möglichkeiten, auf Datenschichtereignisse zu warten:
- Erstellen Sie einen Dienst, der
WearableListenerService
erweitert. - Erstellen Sie eine Aktivität oder Klasse, die die
DataClient.OnDataChangedListener
-Schnittstelle implementiert.
Mit beiden Optionen überschreiben Sie die Datenereignis-Callback-Methoden für die die Sie verarbeiten möchten.
Hinweis:Berücksichtigen Sie bei der Auswahl
eine Listener-Implementierung. Ein WearableListenerService
ist im Manifest der App registriert und kann die App starten, falls dies noch nicht geschehen ist
ausgeführt wird. Wenn Sie nur auf Ereignisse warten müssen, wenn Ihre App bereits ausgeführt wird,
Dies ist häufig bei interaktiven Anwendungen der Fall.
WearableListenerService
Registrieren Sie stattdessen einen Live-Hörer.
Verwenden Sie beispielsweise die Methode addListener
des Objekts DataClient
. Dies kann das System entlasten und den Akkuverbrauch verringern.
WearableListenerService verwenden
Normalerweise erstellen Sie Instanzen von .
WearableListenerService
in Ihrem Wearable und
Handheld-Apps. Wenn Sie jedoch kein Interesse an Datenereignissen
müssen Sie den Dienst nicht in dieser App implementieren.
Beispielsweise können Sie eine Handheld-App haben, die Datenobjekte festlegt und abruft. und eine Wearable-App, die auf diese Updates achtet, um ihre Benutzeroberfläche zu aktualisieren. Die Die Wearable-App aktualisiert keine Datenelemente, sodass die Handheld-App auf Datenereignisse von der Wearable-App warten.
Einige der Ereignisse, die Sie mit
WearableListenerService
sind die folgenden:
- <ph type="x-smartling-placeholder"></ph>
onDataChanged()
: Immer wenn ein Datenelementobjekt erstellt, gelöscht oder geändert wird, löst das System diesen Callback auf allen verbundenen Knoten. - <ph type="x-smartling-placeholder"></ph>
onMessageReceived()
: Eine von einem Knoten gesendete Nachricht wird ausgelöst diesen Callback auf dem Zielknoten. - <ph type="x-smartling-placeholder"></ph>
onCapabilityChanged()
: Wenn eine Funktion verfügbar wird, die von einer Instanz Ihrer App beworben wird im Netzwerk, löst dieses Ereignis diesen Callback aus. Wenn Sie eine Knoten in der Nähe befindet, können Sie <ph type="x-smartling-placeholder"></ph>isNearby()
der im Callback angegebenen Knoten.
Sie können auch auf Ereignisse von
ChannelClient.ChannelCallback
, z. B. onChannelOpened()
.
Alle vorherigen Ereignisse werden in einem Hintergrundthread ausgeführt. nicht im Hauptthread.
So erstellen Sie eine WearableListenerService
:
- Erstellen Sie eine Klasse, die
WearableListenerService
erweitert. - Beobachten Sie Ereignisse, die Sie interessieren, z. B.
onDataChanged()
. - Deklarieren Sie in Ihrem Android-Manifest einen Intent-Filter, um das System über Ihre
WearableListenerService
Mit dieser Deklaration kann das System Ihre -Dienst nach Bedarf.
Das folgende Beispiel zeigt, wie eine einfache WearableListenerService
implementiert wird:
Kotlin
private const val TAG = "DataLayerSample" private const val START_ACTIVITY_PATH = "/start-activity" private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received" class DataLayerListenerService : WearableListenerService() { override fun onDataChanged(dataEvents: DataEventBuffer) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: $dataEvents") } // Loop through the events and send a message // to the node that created the data item. dataEvents.map { it.dataItem.uri } .forEach { uri -> // Get the node ID from the host value of the URI. val nodeId: String = uri.host // Set the data of the message to be the bytes of the URI. val payload: ByteArray = uri.toString().toByteArray() // Send the RPC. Wearable.getMessageClient(this) .sendMessage(nodeId, DATA_ITEM_RECEIVED_PATH, payload) } } }
Java
public class DataLayerListenerService extends WearableListenerService { private static final String TAG = "DataLayerSample"; private static final String START_ACTIVITY_PATH = "/start-activity"; private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received"; @Override public void onDataChanged(DataEventBuffer dataEvents) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: " + dataEvents); } // Loop through the events and send a message // to the node that created the data item. for (DataEvent event : dataEvents) { Uri uri = event.getDataItem().getUri(); // Get the node ID from the host value of the URI. String nodeId = uri.getHost(); // Set the data of the message to be the bytes of the URI. byte[] payload = uri.toString().getBytes(); // Send the RPC. Wearable.getMessageClient(this).sendMessage( nodeId, DATA_ITEM_RECEIVED_PATH, payload); } } }
Im folgenden Abschnitt wird erläutert, wie Sie mit diesem Listener einen Intent-Filter verwenden.
Filter mit WearableListenerService verwenden
Intent-Filter für das im vorherigen Abschnitt gezeigte WearableListenerService
-Beispiel
könnte wie folgt aussehen:
<service android:name=".DataLayerListenerService" android:exported="true" tools:ignore="ExportedService" > <intent-filter> <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> <data android:scheme="wear" android:host="*" android:path="/start-activity" /> </intent-filter> </service>
In diesem Filter wird durch die Aktion DATA_CHANGED
Folgendes ersetzt:
empfohlene Maßnahme BIND_LISTENER
, damit nur spezifische
oder Ihre App starten. Durch diese Änderung wird die Systemeffizienz verbessert
und senkt den Akkuverbrauch und die
In diesem Beispiel wartet die Smartwatch auf den
/start-activity
-Datenelement und die
Das Smartphone wartet auf die Nachrichtenantwort /data-item-received
.
Es gelten die Standardregeln für den Android-Filterabgleich. Sie können mehrere Dienste angeben
pro Manifest, mehrere Intent-Filter pro Dienst, mehrere Aktionen pro Filter,
und mehrere Daten-Stanzas pro Filter. Filter können mit einem Platzhalter-Host oder auf
einer bestimmten. Für den Abgleich mit einem Platzhalterhost verwenden Sie host="*"
. Übereinstimmung
auf einem bestimmten Host, geben Sie host=<node_id>
an.
Sie können auch einen literalen Pfad oder ein Pfadpräfix abgleichen. Gehen Sie dazu wie folgt vor: müssen Sie einen Platzhalter oder einen bestimmten Host angeben. Andernfalls ignoriert das System den von Ihnen angegebenen Pfad.
Weitere Informationen zu den von Wear OS unterstützten Filtertypen findest du in den
API-Referenzdokumentation für
WearableListenerService
Weitere Informationen zu Datenfiltern und Abgleichregeln finden Sie in der API-Referenz
Dokumentation für <data>
Manifest-Element enthält.
Beachten Sie beim Abgleichen von Intent-Filtern zwei wichtige Regeln:
- Wenn für den Intent-Filter kein Schema angegeben ist, ignoriert das System alle anderen URI-Attribute.
- Falls für den Filter kein Host angegeben ist, ignoriert das System alle Pfadattribute.
Live-Zuhörer verwenden
Wenn für Ihre App Datenebenen-Ereignisse nur relevant sind, wenn der Nutzer mit der Anwendung ist, ist kein lang andauernder Dienst erforderlich, um jede Datenänderung zu verarbeiten. In können Sie in einer Aktivität auf Ereignisse warten, indem Sie ein oder der folgenden Oberflächen verwenden:
DataClient.OnDataChangedListener
MessageClient.OnMessageReceivedListener
CapabilityClient.OnCapabilityChangedListener
ChannelClient.ChannelCallback
So erstellen Sie eine Aktivität, die auf Datenereignisse wartet:
- Implementieren Sie die gewünschten Schnittstellen.
- Rufen Sie in der Methode
onCreate()
oderonResume()
Wearable.getDataClient(this).addListener()
,MessageClient.addListener()
,CapabilityClient.addListener()
oderChannelClient.registerChannelCallback()
, um Google Play zu benachrichtigen Dienste, die von Ihrer Aktivität auf Datenschichtereignisse überwacht werden sollen. - Im Jahr
onStop()
oderonPause()
, Registrierung aller Listener mitDataClient.removeListener()
aufheben,MessageClient.removeListener()
,CapabilityClient.removeListener()
oderChannelClient.unregisterChannelCallback()
- Wenn eine Aktivität nur an Ereignissen mit einem bestimmten Pfadpräfix interessiert ist, können Sie einen Listener mit einem geeigneten Präfixfilter hinzufügen, um nur Daten zu empfangen, relevant für den aktuellen Anwendungsstatus sind.
onDataChanged()
,onMessageReceived()
implementierenonCapabilityChanged()
oder Methoden ausChannelClient.ChannelCallback
abhängig von den von Ihnen implementierten Schnittstellen. Diese Methoden werden am dem Hauptthread oder Sie können mitWearableOptions
ein benutzerdefiniertesLooper
-Objekt angeben.
Hier ist ein Beispiel für die Implementierung von DataClient.OnDataChangedListener
:
Kotlin
class MainActivity : Activity(), DataClient.OnDataChangedListener { public override fun onResume() { Wearable.getDataClient(this).addListener(this) } override fun onPause() { Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> if (event.type == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.dataItem.uri) } else if (event.type == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.dataItem.uri) } } } }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { @Override public void onResume() { Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri()); } else if (event.getType() == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri()); } } } }
Filter mit Live-Hörern verwenden
Wie bereits erwähnt, können Sie ebenso wie Sie Intent-Filter für
Manifestbasierte WearableListenerService
-Objekten enthält, können Sie Intent-Filter verwenden, wenn Sie einen Live-Listener über die
Am Körper tragbar
API zu erstellen. Für API-basierte Live-Listener und
Manifest-basierten Listenern.
Ein gängiges Muster besteht darin, einen Listener mit einem bestimmten Pfad- oder Pfadpräfix zu registrieren.
im onResume()
einer Aktivität
und dann den Listener aus der Methode
onPause()
-Methode.
Wenn Sie Listener auf diese Weise implementieren, kann Ihre App selektiver
Ereignisse empfangen und so sein Design und seine Effizienz verbessern können.