Um binäre große Objekte über Bluetooth zu senden, z. B. eine Sprachaufnahme von einem anderen Gerät, können Sie ein
Asset
an ein Datenelement anhängen und es dann im replizierten Datenspeicher ablegen.
Assets übernehmen automatisch das Caching von Daten, um eine erneute Übertragung zu verhindern und die Bluetooth-Bandbreite zu sparen. Ein gängiges Muster ist, dass eine Handheld-App ein Bild herunterlädt, auf eine geeignete Größe für die Anzeige auf dem Wearable verkleinert und als Asset an die Wearable-App überträgt. Die folgenden Beispiele veranschaulichen dieses Muster.
Hinweis: Obwohl die Größe der Datenelemente theoretisch auf 100 KB beschränkt ist, können in der Praxis auch größere Datenelemente verwendet werden. Bei größeren Datenelementen sollten Sie die Daten durch eindeutige Pfade trennen und nicht für alle Daten denselben Pfad verwenden. Die Übertragung großer Assets wirkt sich in vielen Fällen auf die Nutzererfahrung aus. Testen Sie daher Ihre Apps, um sicherzustellen, dass sie beim Übertragen großer Assets eine gute Leistung erzielen.
Asset übertragen
Erstellen Sie das Asset mit einer der create...()
-Methoden in der Klasse
Asset
.
Konvertieren Sie eine Bitmap in einen Bytestream und rufen Sie dann
createFromBytes()
auf, 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()
in
DataMap
oder
PutDataRequest
an ein Datenelement an. Legen Sie das Datenelement dann mit der Methode
putDataItem()
im Datenspeicher ab, wie in den folgenden Beispielen gezeigt.
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);
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 ein Asset erstellt wird, möchten Sie es wahrscheinlich auf der anderen Seite der Verbindung lesen und extrahieren. Hier ein Beispiel für die Implementierung des Callbacks, mit dem eine Asset-Änderung erkannt und das Asset extrahiert wird:
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.