Đồng bộ hoá dữ liệu

Tài liệu này mô tả cách đồng bộ hoá dữ liệu giữa thiết bị Wear OS và điện thoại. Hãy xem hướng dẫn tổng quan để biết thời điểm sử dụng Data Layer API (API Lớp dữ liệu) và thời điểm sử dụng cơ sở hạ tầng của bạn.

Gửi và đồng bộ hoá dữ liệu trực tiếp từ mạng

Xây dựng các ứng dụng Wear OS để giao tiếp trực tiếp qua mạng. Bạn có thể sử dụng cùng các API mà bạn dùng để phát triển cho thiết bị di động, nhưng hãy lưu ý một số điểm khác biệt dành riêng cho thiết bị Wear OS.

Đồng bộ hoá dữ liệu bằng Wear OS Data Layer API (API Lớp dữ liệu)

DataClient hiển thị một API để các thành phần đọc hoặc ghi vào DataItem hoặc Asset.

Bạn có thể đặt các mục dữ liệu và nội dung trong khi không kết nối với bất kỳ thiết bị nào. Chúng được đồng bộ hoá khi các thiết bị thiết lập kết nối mạng. Dữ liệu này là riêng tư đối với ứng dụng của bạn và chỉ ứng dụng của bạn mới có thể truy cập vào dữ liệu này trên các thiết bị khác.

  • DataItem được đồng bộ hoá trên mọi thiết bị trong mạng Wear OS. Chúng thường có kích thước nhỏ.

  • Sử dụng Asset để chuyển một đối tượng lớn hơn, chẳng hạn như hình ảnh. Hệ thống theo dõi những nội dung đã được chuyển và tự động thực hiện việc loại bỏ dữ liệu trùng lặp.

Nghe các sự kiện trong dịch vụ

Mở rộng lớp WearableListenerService. Hệ thống sẽ quản lý vòng đời của WearableListenerService cơ sở, liên kết với dịch vụ khi cần gửi các mục dữ liệu hoặc thông báo, và huỷ liên kết dịch vụ khi không cần hoạt động nào.

Nghe các sự kiện trong hoạt động

Triển khai giao diện OnDataChangedListener. Sử dụng giao diện này thay vì WearableListenerService khi bạn chỉ muốn nghe các thay đổi khi người dùng đang tích cực sử dụng ứng dụng của bạn.

description: Transfer large binary objects, such as images, between Android phones and Wear OS watches using Assets in the Data Layer API. keywords_public: Wear OS, Data Layer API, Assets, Bluetooth data transfer, data synchronization, DataMap, PutDataRequest

Đồng bộ hoá dữ liệu

Để chia sẻ các đối tượng nhị phân lớn qua phương tiện truyền Bluetooth, chẳng hạn như bản ghi âm giọng nói của một thiết bị khác, bạn có thể đính kèm Asset vào một mục dữ liệu rồi đặt mục dữ liệu này vào kho dữ liệu được sao chép. Tuy nhiên, nếu quá trình trao đổi là một lần trao đổi giữa hai thiết bị được kết nối, hãy cân nhắc xem liệu việc chuyển trực tiếp đơn giản hơn có phù hợp hơn không.

Lưu ý: Data Layer API (API Lớp dữ liệu) chỉ có thể gửi thông báo và đồng bộ hoá dữ liệu với điện thoại chạy Android hoặc đồng hồ Wear OS. Nếu thiết bị Wear OS của bạn được ghép nối với một thiết bị iOS thì Data Layer API (API Lớp dữ liệu) sẽ không hoạt động.

Vì lý do này, bạn không nên dùng Data Layer API (API Lớp dữ liệu) làm phương thức chính để giao tiếp với một mạng. Thay vào đó, hãy xây dựng ứng dụng Wear OS theo cùng một mẫu với ứng dụng dành cho điện thoại, kèm một số điểm khác biệt nhỏ như được mô tả trong phần Truy cập mạng và đồng bộ hoá trên thiết bị Wear OS.

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 phổ biến là để một ứng dụng dành cho điện thoại tải hình ảnh xuống, thu nhỏ kích thước phù hợp để hiển thị trên đồng hồ và chia sẻ hình ảnh đó đến ứng dụng đồng hồ dưới dạng thành phần. Những ví dụ dưới đây minh hoạ mẫu này.

Chuyển một tài sản

Tạo nội dung bằng một trong các phương thức create...() trong lớp Asset. Chuyển đổi bitmap thành mảng byte rồi gọi createFromBytes() để tạo thành phần như trong mẫu sau.

private fun createAssetFromBitmap(bitmap: Bitmap): Asset =
    ByteArrayOutputStream().let { byteStream ->
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream)
        Asset.createFromBytes(byteStream.toByteArray())
    }

Tiếp theo, hãy đính kèm thành phần này vào 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ác mẫu sau cho thấy.

Mẫu sau đây sử dụng PutDataRequest:

private fun Context.sendImagePutDataRequest(): Task<DataItem> {

    val asset: Asset = createAssetFromBitmap(BitmapFactory.decodeResource(resources, R.drawable.ic_walk))
    val request: PutDataRequest = PutDataRequest.create("/image").apply {
        putAsset("profileImage", asset)
    }
    val putTask: Task<DataItem> = Wearable.getDataClient(this).putDataItem(request)

    return putTask
}

Mẫu sau đây sử dụng PutDataMapRequest:

private fun Context.sendImagePutDataMapRequest(): Task<DataItem> {

    val asset: Asset = createAssetFromBitmap(BitmapFactory.decodeResource(resources, R.drawable.ic_walk))
    val request: PutDataRequest = PutDataMapRequest.create("/image").run {
        dataMap.putAsset("profileImage", asset)
        asPutDataRequest()
    }
    val putTask: Task<DataItem> = Wearable.getDataClient(this).putDataItem(request)

    return putTask
}

Nhận nội dung

Sau khi tạo một nội dung, bạn thường đọc và trích xuất nội dung đó ở phía bên kia của kết nối. Ví dụ sau đây cho thấy cách triển khai lệnh gọi lại để phát hiện thay đổi về thành phần và trích xuất thành phần đó:

override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents
        .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" }
        .forEach { event ->
            val asset = DataMapItem.fromDataItem(event.dataItem)
                .dataMap.getAsset("profileImage")

            asset?.let { safeAsset ->
                lifecycleScope.launch {
                    val bitmap = loadBitmapFromAsset(safeAsset)
                    // Do something with the bitmap
                }
            }
        }
}

private suspend fun loadBitmapFromAsset(asset: Asset): Bitmap? = withContext(Dispatchers.IO) {
    try {
        val assetResult = Wearable.getDataClient(this@DataLayerActivity2)
            .getFdForAsset(asset)
            .await()

        assetResult?.inputStream?.use { inputStream ->
            BitmapFactory.decodeStream(inputStream)
        }
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

Để biết thêm thông tin, hãy xem dự án mẫu DataLayer trên GitHub.