Per inviare oggetti binari di grandi dimensioni tramite il trasporto Bluetooth, ad esempio una registrazione vocale di un altro dispositivo, puoi allegare un
Asset
a un elemento di dati e poi inserirlo nell'archivio dati replicato.
Gli asset gestiscono automaticamente la memorizzazione nella cache dei dati per impedire la ritrasmissione e conservare la larghezza di banda Bluetooth. Di solito, un'app portatile scarica un'immagine, la restringe alle dimensioni appropriate per la visualizzazione sul dispositivo indossabile e la trasmette all'app indossabile come asset. I seguenti esempi mostrano questo modello.
Nota: sebbene le dimensioni degli elementi di dati siano teoricamente limitate a 100 kB, in pratica è possibile utilizzare elementi di dati più grandi. Per elementi di dati di dimensioni maggiori, separa i dati in base a percorsi univoci ed evita di utilizzare un unico percorso per tutti i dati. In molti casi, il trasferimento di asset di grandi dimensioni influisce sull'esperienza utente, quindi testa le tue app per assicurarti che abbiano un buon rendimento durante il trasferimento di asset di grandi dimensioni.
Trasferire una risorsa
Crea l'asset utilizzando uno dei metodi create...()
nella classe
Asset
.
Converti una bitmap in un flusso di byte, quindi chiama
createFromBytes()
per creare l'asset, come mostrato nell'esempio seguente.
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()); }
Successivamente, associa l'asset a un elemento di dati con il metodo putAsset()
in
DataMap
o
PutDataRequest
. Quindi, inserisci l'elemento di dati nel datastore utilizzando il metodo
putDataItem()
, come mostrato nei seguenti esempi.
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);
Ricevi asset
Quando viene creato un asset, è consigliabile leggerlo ed estrarlo dall'altro lato della connessione. Ecco un esempio di come implementare il callback per rilevare una modifica dell'asset ed estrarre l'asset:
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); }
Per maggiori informazioni, consulta il progetto di esempio Datalayer su GitHub.