Sincronizar dados

Este documento descreve como sincronizar dados entre um dispositivo Wear OS e um smartphone. Consulte as orientações gerais para saber quando usar a API Camada de Dados e quando usar sua infraestrutura.

Enviar e sincronizar dados diretamente da rede

Crie apps para Wear OS que se comuniquem diretamente com a rede. Use as mesmas APIs utilizadas no desenvolvimento para dispositivos móveis, mas não se esqueça das especificidades do Wear OS.

Sincronizar dados usando a API Camada de Dados do Wear OS

Um DataClient expõe uma API para que os componentes leiam ou gravem em um DataItem ou Asset.

É possível definir itens de dados e recursos mesmo quando eles não estão conectados a um dispositivo. Eles são sincronizados quando os dispositivos estabelecem uma conexão de rede. Esses dados são particulares e só podem ser acessados pelo seu app em outros dispositivos.

  • Um DataItem é sincronizado em todos os dispositivos conectados a uma rede do Wear OS. Em geral, esses itens são pequenos.

  • Use um Asset para transferir um objeto maior, como uma imagem. O sistema monitora quais recursos já foram transferidos e realiza a eliminação de duplicação automaticamente.

Detectar eventos em serviços

Estenda a classe WearableListenerService. O sistema gerencia o ciclo de vida do WearableListenerService base, vinculando-o ao serviço quando é necessário enviar itens de dados ou mensagens e desvinculando o serviço quando nenhuma ação é necessária.

Detectar eventos em atividades

Implementar a interface OnDataChangedListener. Use essa interface em vez de um WearableListenerService quando quiser detectar mudanças apenas quando o usuário estiver usando o app ativamente.

description: Transfira objetos binários grandes, como imagens, entre smartphones Android e relógios Wear OS usando recursos na API Data Layer. keywords_public: Wear OS, API Data Layer, recursos, transferência de dados por Bluetooth, sincronização de dados, DataMap, PutDataRequest

Sincronizar dados

Para compartilhar objetos binários grandes por Bluetooth, como uma gravação de voz de outro dispositivo, anexe um Asset a um item de dados e, em seguida, coloque o item de dados no repositório de dados replicados.

Observação: a API Camada de Dados pode enviar mensagens e sincronizar dados apenas com smartphones Android ou relógios Wear OS. Ou seja, se o dispositivo Wear OS estiver pareado com um dispositivo iOS, a API Camada de dados não vai funcionar.

Por esse motivo, não use a API Data Layer como principal maneira de se comunicar com uma rede. Em vez disso, siga o mesmo padrão no app para Wear OS e no app Telefone, com algumas pequenas diferenças, conforme descrito em Acesso à rede e sincronização no Wear OS.

Os recursos processam automaticamente o armazenamento de dados em cache para evitar a retransmissão e conservar a largura de banda do Bluetooth. É um padrão comum que um app Telefone faça o download de uma imagem, diminua a imagem para um tamanho adequado para exibição no relógio e a compartilhe com o app para smartwatch como um recurso. Os exemplos abaixo demonstram esse padrão.

Transferir um recurso

Crie o recurso usando um dos métodos create...() na classe Asset. Converta um bitmap em uma matriz de bytes e depois chame createFromBytes() para criar o recurso, conforme mostrado no exemplo abaixo.

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

Depois, anexe o recurso a um item de dados com o método putAsset() em DataMap ou PutDataRequest. Em seguida, coloque o item de dados no armazenamento de dados usando o método putDataItem(), conforme mostrado nos exemplos abaixo.

O exemplo a seguir usa 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
}

O exemplo a seguir usa 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
}

Receber recursos

Depois de criar um recurso, você geralmente o lê e extrai do outro lado da conexão. O exemplo a seguir mostra como implementar o callback para detectar uma mudança e extrair o recurso:

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

Para mais informações, consulte o projeto de exemplo DataLayer no GitHub.