Cómo transferir recursos en Wear

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Para enviar BLOB de datos binarios mediante Bluetooth, como una grabación de voz desde otro dispositivo, puedes adjuntar un Asset a un elemento de datos y, luego, colocar este elemento en el almacén de datos replicado.

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 de mano descargue una imagen, reduzca su tamaño a uno apropiado a fin de mostrarla en el wearable y la transmita como recurso a la app para wearables. En los siguientes ejemplos, se muestra este patrón.

Si bien el tamaño de los elementos de datos está limitado a 100 KB, los desarrolladores no están limitados a ese tamaño. En el caso de los elementos de datos más grandes, los desarrolladores deben separar los datos por rutas de acceso únicas y evitar el uso de una sola para todos los datos. La transferencia de recursos grandes afecta la experiencia del usuario en muchos casos, por lo que debes probar 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, como se muestra en el siguiente ejemplo.

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 en el almacén de datos con putDataItem(), como se muestra en el siguiente ejemplo:

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 para 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);
}