Persistente Daten synchronisieren

In diesem Dokument wird die Synchronisierung von Daten zwischen einem Wear OS-Gerät und einem Mobilgerät.

Daten direkt über das Netzwerk senden und synchronisieren

Erstellen von Wear OS-Apps zur direkten Kommunikation mit dem Netzwerk. Gleiche APIs, die Sie für die Entwicklung für Mobilgeräte verwenden, aber einige Wear OS-spezifische APIs beibehalten Unterschiede berücksichtigen.

Daten mit der Wear OS Data Layer API synchronisieren

Ein DataClient stellt eine API für Komponenten zur Verfügung, die in einem DataItem- oder Asset

Sie können Datenelemente und Assets festlegen, wenn keine Geräte verbunden sind. Sie werden synchronisiert, wenn die Geräte eine Netzwerkverbindung herstellen. Diese Daten ist für deine App privat und kann nur für deine App auf anderen Geräten verwendet werden.

  • Ein DataItem wird auf allen Geräten in einem Wear OS-Netzwerk synchronisiert. Sie sind in der Regel klein.

  • Verwende ein Asset, um ein größeres Objekt, z. B. ein Bild, zu übertragen. Das System verfolgt, welche Assets bereits übertragen wurden, und wird ausgeführt automatische Deduplizierung.

Auf Ereignisse in Diensten warten

Erweitern Sie die Klasse WearableListenerService. Das System verwaltet Lebenszyklus des Basis-WearableListenerService, Bindung an den Dienst, wenn er muss Datenelemente oder Nachrichten senden und die Bindung des Dienstes aufheben, wenn keine Arbeit ausgeführt wird. erforderlich.

Auf Ereignisse in Aktivitäten warten

Implementieren Sie die OnDataChangedListener-Schnittstelle. Stattdessen diese Schnittstelle verwenden eines WearableListenerService, wenn Sie nur dann auf Änderungen warten möchten, wenn der Nutzer Ihre App aktiv verwenden.

Daten übertragen

Um binäre große Objekte über den Bluetooth-Transport zu senden, z. B. eine Sprachaufnahme von einem anderen Gerät abgerufen, können Sie <ph type="x-smartling-placeholder"></ph> Asset zu einem Datenelement hinzu und speichern es dann in den replizierten Datenspeicher.

Assets verarbeiten das Caching von Daten automatisch, um eine erneute Übertragung und um Bluetooth-Bandbreite zu sparen. Ein gängiges Muster ist, dass eine Handheld-App ein Bild herunterlädt, es auf eine geeignete Größe verkleinert. zur Anzeige auf dem Wearable und überträgt es als Asset an die Wearable-App. Die folgenden Beispiele dieses Musters demonstrieren.

Hinweis: Obwohl die Größe von Datenelementen theoretisch auf 100 KB begrenzt ist, können in der Praxis größere Datenelemente verwendet werden. Für größere Datenelemente verwenden, Daten durch eindeutige Pfade trennen und mit einem einzigen Pfad für alle Daten. Die Übertragung großer Assets wirkt sich Testen Sie Ihre Apps daher, um sicherzustellen, dass sie bei der Übertragung großer Assets gut funktionieren.

Asset übertragen

Erstellen Sie das Asset mithilfe einer der create...()-Methoden in der Asset. Konvertiere eine Bitmap in einen Bytestream und rufe dann <ph type="x-smartling-placeholder"></ph> createFromBytes() um das Asset zu erstellen, wie im folgenden Beispiel gezeigt.

Kotlin

private fun createAssetFromBitmap(bitmap: Bitmap): Asset =
    ByteArrayOutputStream().let { byteStream ->
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream)
        Asset.createFromBytes(byteStream.toByteArray())
    }

Java

private static Asset createAssetFromBitmap(Bitmap bitmap) {
    final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
    return Asset.createFromBytes(byteStream.toByteArray());
}

Als Nächstes hängen Sie das Asset mit der Methode putAsset() an ein Datenelement an: DataMap oder PutDataRequest Legen Sie das Datenelement dann mithilfe der Methode <ph type="x-smartling-placeholder"></ph> putDataItem()-Methode, wie in den folgenden Beispielen gezeigt.

Im folgenden Beispiel wird PutDataRequest verwendet:

Kotlin

val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap ->
    createAssetFromBitmap(bitmap)
}
val request: PutDataRequest = PutDataRequest.create("/image").apply {
    putAsset("profileImage", asset)
}
val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)

Java

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Asset asset = createAssetFromBitmap(bitmap);
PutDataRequest request = PutDataRequest.create("/image");
request.putAsset("profileImage", asset);
Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);

Im folgenden Beispiel wird PutDataMapRequest verwendet:

Kotlin

val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap ->
    createAssetFromBitmap(bitmap)
}
val request: PutDataRequest = PutDataMapRequest.create("/image").run {
    dataMap.putAsset("profileImage", asset)
    asPutDataRequest()
}
val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)

Java

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Asset asset = createAssetFromBitmap(bitmap);
PutDataMapRequest dataMap = PutDataMapRequest.create("/image");
dataMap.getDataMap().putAsset("profileImage", asset);
PutDataRequest request = dataMap.asPutDataRequest();
Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);

Assets erhalten

Wenn Sie ein Asset erstellen, möchten Sie es wahrscheinlich auf der anderen Seite der Verbindung. Hier ist ein Beispiel für die Implementierung der verwenden, um eine Asset-Änderung zu erkennen und das Asset zu extrahieren:

Kotlin

override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents
            .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" }
            .forEach { event ->
                val bitmap: Bitmap? = DataMapItem.fromDataItem(event.dataItem)
                        .dataMap.getAsset("profileImage")
                        .let { asset -> loadBitmapFromAsset(asset) }
                // Do something with the bitmap
            }
}

fun loadBitmapFromAsset(asset: Asset): Bitmap? {
    // Convert asset into a file descriptor and block until it's ready
    val assetInputStream: InputStream? =
            Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset))
            ?.inputStream

    return assetInputStream?.let { inputStream ->
        // Decode the stream into a bitmap
        BitmapFactory.decodeStream(inputStream)
    } ?: run {
        Log.w(TAG, "Requested an unknown Asset.")
        null
    }
}

Java

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
  for (DataEvent event : dataEvents) {
    if (event.getType() == DataEvent.TYPE_CHANGED &&
        event.getDataItem().getUri().getPath().equals("/image")) {
      DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
      Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage");
      Bitmap bitmap = loadBitmapFromAsset(profileAsset);
      // Do something with the bitmap
    }
  }
}

public Bitmap loadBitmapFromAsset(Asset asset) {
    if (asset == null) {
        throw new IllegalArgumentException("Asset must be non-null");
    }
    // Convert asset into a file descriptor and block until it's ready
    InputStream assetInputStream =
        Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset))
            .getInputStream();
    if (assetInputStream == null) {
        Log.w(TAG, "Requested an unknown Asset.");
        return null;
    }
    // Decode the stream into a bitmap
    return BitmapFactory.decodeStream(assetInputStream);
}

Weitere Informationen finden Sie im DataLayer-Beispielprojekt auf GitHub.