Para enviar grandes BLOB de datos binarios, como imágenes, mediante Bluetooth, puedes adjuntar un Asset
a un elemento de datos y, luego, colocar ese elemento en el almacén de datos de réplica.
Nota: Si bien una app para Wear se puede comunicar con una app para teléfonos mediante la API de Data Layer que se menciona más abajo, no se recomienda establecer conexión con una red usando esta API.
Los recursos manejan automáticamente el almacenamiento en caché de datos para evitar la retransmisión y conservar el ancho de banda de Bluetooth. Un patrón común es que una app para dispositivos portátiles descargue una imagen, reduzca su tamaño a uno apropiado para mostrarla en el wearable y la transmita como recurso a la app para wearables. En los siguientes ejemplos, se muestra este patrón.
Nota: Aunque el tamaño de los elementos de datos está limitado a 100 KB, los recursos pueden ser tan grandes como se desee. Sin embargo, como la transferencia de recursos grandes en muchos casos afecta la experiencia del usuario, prueba tus apps para asegurarte de que funcionen bien si transfieres recursos grandes.
Consulta los siguientes recursos relacionados:
Cómo transferir un recurso
Crea el recurso usando uno de los métodos create...()
en la clase Asset
.
Aquí convertimos un mapa de bits en un flujo de bytes y, luego, llamamos a createFromBytes()
para crear el recurso.
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()); }
Cuando tengas un recurso, adjúntalo a un elemento de datos con el método putAsset()
en DataMap
o PutDataRequest
; luego, coloca el elemento de datos en el almacén de datos con putDataItem()
:
Cómo usar PutDataRequest
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);
Cómo usar PutDataMapRequest
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);
Cómo recibir recursos
Cuando se crea un recurso, es probable que quieras leerlo y extraerlo en otro extremo de la conexión. A continuación, se incluye un ejemplo de cómo implementar la devolución de llamada para detectar un cambio de recurso y extraerlo:
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); }