Datenelemente mit der Data Layer API synchronisieren

Eine DataItem definiert die Schnittstelle, die das System zum Synchronisieren von Daten zwischen Handhelds und Wearables verwendet. Ein DataItem besteht in der Regel aus den folgenden Komponenten:

  • Nutzlast:Ein Byte-Array, das Sie mit Daten festlegen können. So können Sie Ihre eigene Objektserialisierung und ‑deserialisierung durchführen. Die Größe der Nutzlast ist auf 100 KB begrenzt.
  • Pfad:Ein eindeutiger String, der mit einem Schrägstrich beginnen muss, z. B. "/path/to/data".

Hinweis:Mit der Data Layer API können nur Nachrichten gesendet und Daten mit Android-Smartphones oder Wear OS-Smartwatches synchronisiert werden. Wenn Ihr Wear OS-Gerät mit einem iOS-Gerät gekoppelt ist, funktioniert die Data Layer API nicht.

Verwenden Sie die Data Layer API daher nicht als primäre Methode für die Kommunikation mit einem Netzwerk. Folgen Sie stattdessen dem gleichen Muster wie bei einer mobilen App, mit einigen geringfügigen Unterschieden.

Normalerweise implementieren Sie DataItem nicht direkt. Stattdessen gehen Sie so vor:

  1. Erstellen Sie ein PutDataRequest-Objekt und geben Sie einen Stringpfad an, um das Element eindeutig zu identifizieren.
  2. Rufen Sie setData() auf, um die Nutzlast festzulegen.
  3. Wenn sich eine Verzögerung bei der Synchronisierung negativ auf die Nutzererfahrung auswirken würde, rufen Sie setUrgent() auf.
  4. Verwenden Sie die Methode putDataItem der Klasse DataClient, um das System aufzufordern, das Datenelement zu erstellen.

Beim Anfordern von Datenelementen gibt das System Objekte zurück, die die DataItem-Schnittstelle korrekt implementieren. Anstatt mit Rohbytes über setData() zu arbeiten, empfehlen wir jedoch, eine Datenzuordnung zu verwenden, die ein Datenelement mit einer Bundle-ähnlichen Schnittstelle bereitstellt.

Weitere Informationen finden Sie in der DataLayer-Beispiel-App.

Daten mit einer Datenübersicht synchronisieren

Verwenden Sie nach Möglichkeit die Klasse DataMap. Bei diesem Ansatz arbeiten Sie mit Datenelementen in Form eines Android-Bundle. Das System übernimmt die Objektserialisierung und ‑deserialisierung für Sie und Sie können Daten mit Schlüssel/Wert-Paaren bearbeiten.

So verwenden Sie eine Datenkarte:

  1. Erstellen Sie ein PutDataMapRequest-Objekt und legen Sie den Pfad des Datenobjekts fest.

    Hinweis:Der Pfadstring ist eine eindeutige Kennung für das Datenelement, über die Sie von beiden Seiten der Verbindung darauf zugreifen können. Der Pfad muss mit einem Schrägstrich beginnen. Wenn Sie hierarchische Daten in Ihrer App verwenden, erstellen Sie ein Pfadschema, das der Struktur der Daten entspricht.

  2. Rufen Sie PutDataMapRequest.getDataMap() auf, um eine Datenzuordnung zu erhalten, für die Sie Werte festlegen können.
  3. Legen Sie Werte für die Datenzuordnung mit den put...()-Methoden fest, z. B. putString().
  4. Wenn sich eine Verzögerung bei der Synchronisierung negativ auf die Nutzererfahrung auswirken würde, rufen Sie setUrgent() auf.
  5. Rufen Sie PutDataMapRequest.asPutDataRequest() auf, um ein PutDataRequest-Objekt abzurufen.
  6. Verwenden Sie die Methode putDataItem der Klasse DataClient, um das System aufzufordern, das Datenelement zu erstellen.

    Hinweis:Wenn das Smartphone und die Wearable-Geräte getrennt sind, werden die Daten gepuffert und synchronisiert, sobald die Verbindung wiederhergestellt wird.

Die Methode increaseCounter() im folgenden Beispiel zeigt, wie Sie eine Datenzuordnung erstellen und Daten darin einfügen:

Kotlin

private const val COUNT_KEY = "com.example.key.count"

class MainActivity : Activity() {

    private lateinit var dataClient: DataClient
    private var count = 0
    ...
    // Create a data map and put data in it
    private fun increaseCounter() {
        val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run {
            dataMap.putInt(COUNT_KEY, count++)
            asPutDataRequest()
        }
        val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)
    }
    ...
}

Java

public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";
    private DataClient dataClient;
    private int count = 0;
    ...
    // Create a data map and put data in it
    private void increaseCounter() {
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
        Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq);
    }
  ...
}

Weitere Informationen zum Umgang mit Tasks finden Sie in der Referenzdokumentation.

Achtung:Bevor Sie die Wearable Data Layer API verwenden, prüfen Sie, ob sie auf einem Gerät verfügbar ist. Andernfalls tritt eine Ausnahme auf. Verwenden Sie die Klasse GoogleApiAvailability, wie sie in Horologist implementiert ist.

DataItem-Priorität festlegen

Die DataClient API ermöglicht dringende Anfragen zum Synchronisieren von DataItem-Objekten. Normalerweise verzögert das System die Übermittlung von Datenelementen an das Wear OS-Netzwerk, um die Akkulaufzeit von Nutzergeräten zu verlängern. Wenn sich eine Verzögerung bei der Synchronisierung von Datenelementen jedoch negativ auf die Nutzerfreundlichkeit auswirkt, können Sie sie als dringend markieren. In einer Fernbedienungs-App, in der der Nutzer erwartet, dass seine Aktionen sofort berücksichtigt werden, können Sie beispielsweise das System veranlassen, Ihre Daten sofort zu synchronisieren, indem Sie setUrgent() aufrufen.

Wenn Sie setUrgent() nicht aufrufen, kann es bis zu 30 Minuten dauern, bis nicht dringende Daten synchronisiert werden. Normalerweise dauert es aber nur wenige Minuten. Die Standarddringlichkeit ist „nicht dringend“. Wenn Sie das Verhalten der sofortigen Synchronisierung aus früheren Versionen der Wear OS API beibehalten möchten, müssen Sie setUrgent() verwenden.

Auf Datenartikelevents warten

Wenn sich auf einer Seite der Datenschichtverbindung ein Datenelement ändert, benachrichtigen Sie den Nutzer über alle Änderungen auf der anderen Seite der Verbindung. Dazu müssen Sie einen Listener für Datenartikelevents implementieren.

Das Code-Snippet im folgenden Beispiel benachrichtigt die App, wenn sich der Wert des im vorherigen Beispiel definierten Zählers ändert:

Kotlin

private const val COUNT_KEY = "com.example.key.count"

class MainActivity : Activity(), DataClient.OnDataChangedListener {

    private var count = 0

    override fun onResume() {
        super.onResume()
        Wearable.getDataClient(this).addListener(this)
    }

    override fun onPause() {
        super.onPause()
        Wearable.getDataClient(this).removeListener(this)
    }

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            // DataItem changed
            if (event.type == DataEvent.TYPE_CHANGED) {
                event.dataItem.also { item ->
                    if (item.uri.path.compareTo("/count") == 0) {
                        DataMapItem.fromDataItem(item).dataMap.apply {
                            updateCount(getInt(COUNT_KEY))
                        }
                    }
                }
            } else if (event.type == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    // Method to update the count
    private fun updateCount(int: Int) { ... }
    ...
}

Java

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {
    private static final String COUNT_KEY = "com.example.key.count";
    private int count = 0;

    @Override
    protected void onResume() {
        super.onResume();
        Wearable.getDataClient(this).addListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Wearable.getDataClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // DataItem changed
                DataItem item = event.getDataItem();
                if (item.getUri().getPath().compareTo("/count") == 0) {
                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                    updateCount(dataMap.getInt(COUNT_KEY));
                }
            } else if (event.getType() == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    // Method to update the count
    private void updateCount(int c) { ... }
    ...
}

Diese Aktivität implementiert die DataClient.OnDataChangedListener-Schnittstelle. Die Aktivität fügt sich selbst als Listener für DataItem-Ereignisse in der onResume()-Methode hinzu und entfernt den Listener in der onPause()-Methode. Eine Implementierung mit Bildern, Ansichten und Diensten finden Sie in der DataLayer Sample-App.

Sie können den Listener auch als Dienst implementieren. Weitere Informationen finden Sie unter Auf Data Layer-Ereignisse warten.