Datenelemente mit der Data Layer API synchronisieren

Ein DataItem definiert die Schnittstelle, über die das System Daten zwischen Handhelds und Wearables synchronisiert. Ein DataItem besteht im Allgemeinen aus den folgenden Komponenten:

  • Nutzlast: Ein Byte-Array, das Sie mit Daten festlegen können, um Ihre eigene Objektserialisierung und Deserialisierung vorzunehmen. 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:Die Data Layer API kann nur mit Android-Smartphones oder Wear OS-Smartwatches Nachrichten senden und Daten synchronisieren. 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 zur Kommunikation mit einem Netzwerk. Folge stattdessen demselben Muster wie bei einer mobilen App, mit einigen geringfügigen Unterschieden.

Normalerweise implementieren Sie DataItem nicht direkt. Gehen Sie stattdessen so vor:

  1. Erstellen Sie ein PutDataRequest-Objekt und geben Sie einen Stringpfad zur eindeutigen Identifizierung des Elements an.
  2. Rufen Sie setData() auf, um die Nutzlast festzulegen.
  3. Wenn eine Verzögerung bei der Synchronisierung die Nutzerfreundlichkeit beeinträchtigen würde, rufe setUrgent() auf.
  4. Verwenden Sie die Methode putDataItem der Klasse DataClient, um das System zum Erstellen des Datenelements zu veranlassen.

Wenn Datenelemente angefordert werden, gibt das System Objekte zurück, die die DataItem-Schnittstelle ordnungsgemäß implementieren. Anstatt jedoch mit setData() mit Rohbyte zu arbeiten, empfehlen wir die Datenzuordnung, die ein Datenelement mit einer Bundle-ähnlichen Schnittstelle verfügbar macht.

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

Daten mit einer Datenzuordnung synchronisieren

Verwenden Sie nach Möglichkeit die Klasse DataMap. Bei diesem Ansatz können Sie mit Datenelementen in Form einer Android-Bundle arbeiten, sodass das System die Objektserialisierung und Deserialisierung für Sie übernimmt. Außerdem können Sie Daten mit Schlüssel/Wert-Paaren bearbeiten.

So verwenden Sie eine Datenzuordnung:

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

    Hinweis: Der Pfadstring ist eine eindeutige Kennung für das Datenelement, auf die Sie von beiden Seiten der Verbindung aus zugreifen können. Der Pfad muss mit einem Schrägstrich beginnen. Wenn Sie in Ihrer Anwendung hierarchische Daten 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 mit den put...()-Methoden Werte für die Datenzuordnung fest, z. B. putString().
  4. Wenn eine Verzögerung bei der Synchronisierung die Nutzerfreundlichkeit beeinträchtigen würde, rufe setUrgent() auf.
  5. Rufen Sie PutDataMapRequest.asPutDataRequest() auf, um ein PutDataRequest-Objekt zu erhalten.
  6. Verwenden Sie die Methode putDataItem der Klasse DataClient, um das System zum Erstellen des Datenelements zu veranlassen.

    Hinweis:Wenn das Mobiltelefon und das Wearable getrennt sind, werden die Daten zwischengespeichert und synchronisiert, sobald die Verbindung wiederhergestellt ist.

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.

DataItem-Priorität festlegen

Die DataClient API ermöglicht dringende Anfragen zur Synchronisierung von DataItem-Objekten. Normalerweise verzögert das System die Übermittlung von Datenelementen an das Wear OS-Netzwerk, um die Akkulaufzeit der Nutzergeräte zu verbessern. Wenn sich eine Verzögerung bei der Synchronisierung von Datenelementen jedoch negativ auf die Nutzererfahrung auswirkt, kannst du sie als dringend markieren. Beispielsweise kannst du in einer Fernbedienungs-App, in der der Nutzer erwartet, dass seine Aktionen sofort wiedergegeben werden, die Datenelemente durch Aufrufen von setUrgent() sofort synchronisieren lassen.

Wenn Sie setUrgent() nicht aufrufen, dauert es möglicherweise bis zu 30 Minuten, bis das System nicht dringende Datenelemente synchronisiert. In der Regel beträgt die Verzögerung jedoch nur wenige Minuten. Da die standardmäßige Dringlichkeit nicht dringend ist, müssen Sie setUrgent() verwenden, wenn Sie das sofortige Synchronisierungsverhalten aus früheren Versionen der Wear OS API beibehalten müssen.

Auf Datenelementereignisse warten

Wenn auf einer Seite der Datenschichtverbindung ein Datenelement geändert wird, benachrichtigen Sie den Nutzer über die Änderungen auf der anderen Seite der Verbindung. Implementieren Sie dazu einen Listener für Datenelementereignisse.

Das Code-Snippet im folgenden Beispiel benachrichtigt die Anwendung, 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) { ... }
    ...
}

Mit dieser Aktivität wird die Schnittstelle DataClient.OnDataChangedListener implementiert. Die Aktivität fügt sich selbst als Listener für Datenelementereignisse innerhalb der Methode onResume() hinzu und entfernt den Listener aus der Methode onPause(). Eine Implementierung mit Bildern, Aufrufen von Modellen und Diensten finden Sie in der DataLayer-Beispiel-App.

Sie können den Listener auch als Dienst implementieren. Weitere Informationen finden Sie unter Auf Datenschichtereignisse warten.