Chuyển nội dung trên Wear

Stay organized with collections Save and categorize content based on your preferences.

Để gửi blob dữ liệu nhị phân qua phương tiện truyền Bluetooth, chẳng hạn như bản ghi âm giọng nói từ một thiết bị khác, bạn có thể đính kèm Asset vào một mục dữ liệu, sau đó đặt mục dữ liệu đó vào kho dữ liệu được sao chép.

Các nội dung tự động xử lý việc lưu dữ liệu vào bộ nhớ đệm để ngăn việc truyền tải lại và tiết kiệm băng thông Bluetooth. Một mẫu kiểm thử phổ biến là để một ứng dụng cầm tay tải hình ảnh xuống, thu nhỏ kích thước phù hợp để hiển thị trên thiết bị đeo và truyền hình ảnh đó đến ứng dụng cho thiết bị đeo dưới dạng nội dung. Các ví dụ sau đây minh hoạ cho mẫu này.

Mặc dù kích thước của các mục dữ liệu được giới hạn ở mức 100KB, nhưng các nhà phát triển không bị giới hạn ở kích thước đó. Đối với các mục dữ liệu lớn hơn, nhà phát triển nên phân tách dữ liệu bằng các đường dẫn riêng biệt và tránh sử dụng một đường dẫn duy nhất cho tất cả các dữ liệu. Việc chuyển các nội dung lớn sẽ ảnh hưởng đến trải nghiệm người dùng trong nhiều trường hợp. Vì vậy, hãy kiểm thử ứng dụng để đảm bảo ứng dụng hoạt động tốt khi chuyển các nội dung lớn.

Hãy tham khảo các tài nguyên liên quan sau:

Chuyển một nội dung

Tạo nội dung bằng một trong các phương thức create...() trong lớp Asset. Ở đây, chúng ta sẽ chuyển đổi một bitmap thành một luồng byte rồi gọi createFromBytes() để tạo nội dung, như trong mẫu sau.

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

Khi bạn có một nội dung, hãy đính kèm nội dung đó vào một mục dữ liệu bằng phương thức putAsset() trong DataMap hoặc PutDataRequest, sau đó đưa mục dữ liệu vào kho dữ liệu bằng phương thức putDataItem() như được hiển thị trong mẫu sau:

Sử dụng 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);

Sử dụng 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);

Nhận nội dung

Khi một nội dung được tạo, có thể bạn sẽ muốn đọc và trích xuất nội dung đó ở phía bên kia của kết nối. Dưới đây là ví dụ về cách triển khai lệnh gọi lại để phát hiện thay đổi về nội dung và trích xuất nội dung đó:

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