Sincronizza dati

Questo documento descrive come sincronizzare i dati tra un dispositivo Wear OS e uno smartphone. Consulta le indicazioni generali per sapere quando utilizzare l'API Livello dati e quando utilizzare la tua infrastruttura.

Invia e sincronizza i dati direttamente dalla rete

Crea app per Wear OS per comunicare direttamente con la rete. Utilizza le stesse API che usi per lo sviluppo mobile, ma tieni presente alcune differenze specifiche di Wear OS.

Sincronizza i dati utilizzando l'API Wear OS Data Layer

Un DataClient espone un'API per consentire ai componenti di leggere o scrivere in un DataItem o Asset.

È possibile impostare elementi dati e asset anche se non è connesso alcun dispositivo. Vengono sincronizzati quando i dispositivi stabiliscono una connessione di rete. Questi dati sono privati per la tua app e sono accessibili solo alla tua app su altri dispositivi.

  • Un DataItem viene sincronizzato su tutti i dispositivi di una rete Wear OS. In genere sono di piccole dimensioni.

  • Utilizza un Asset per trasferire un oggetto più grande, ad esempio un'immagine. Il sistema tiene traccia degli asset già trasferiti ed esegue automaticamente la deduplicazione.

Ascolta gli eventi nei servizi

Estendi la classe WearableListenerService. Il sistema gestisce il ciclo di vita della classe base WearableListenerService, eseguendo il binding al servizio quando deve inviare elementi dati o messaggi e scollegando il servizio quando non è necessario alcun lavoro.

Ascolta gli eventi nelle attività

Implementa l'interfaccia OnDataChangedListener. Utilizza questa interfaccia anziché un WearableListenerService quando vuoi ascoltare le modifiche solo quando l'utente utilizza attivamente la tua app.

description: Trasferisci oggetti binari di grandi dimensioni, come le immagini, tra smartphone Android e smartwatch Wear OS utilizzando gli asset nell'API Livello dati. keywords_public: Wear OS, API Livello dati, asset, trasferimento di dati Bluetooth, sincronizzazione dei dati, DataMap, PutDataRequest

Sincronizza i dati

Per condividere oggetti binari di grandi dimensioni tramite il trasporto Bluetooth, ad esempio una registrazione vocale da un altro dispositivo, puoi allegare un Asset a un elemento dati e poi inserire l'elemento dati nel datastore replicato.

Nota: l'API Livello dati può inviare messaggi e sincronizzare i dati solo con smartphone con Android o smartwatch Wear OS. Se un dispositivo Wear OS è accoppiato a un dispositivo iOS, l'API Livello dati non funzionerà.

Per questo motivo, non utilizzare l'API Livello dati come metodo principale per comunicare con una rete. Segui invece lo stesso pattern nell'app per Wear OS e nell'app Telefono, con alcune piccole differenze, come descritto in Accesso alla rete e sincronizzazione su Wear OS.

Gli asset gestiscono automaticamente la memorizzazione nella cache dei dati per impedire la ritrasmissione e conservare la larghezza di banda Bluetooth. Un pattern comune è che un'app per smartphone scarichi un'immagine, la riduca a una dimensione appropriata per la visualizzazione sullo smartwatch e la condivida con l'app per smartwatch come asset. I seguenti esempi mostrano questo pattern.

Trasferisci un asset

Crea l'asset utilizzando uno dei metodi create...() nella classe Asset. Converti una bitmap in un array di byte e poi chiama createFromBytes() per creare l'asset, come mostrato nell'esempio seguente.

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

Poi, collega l'asset a un elemento dati con il metodo putAsset() in DataMap o PutDataRequest. Poi inserisci l'elemento dati nel datastore utilizzando il metodo putDataItem(), come mostrato negli esempi seguenti.

L'esempio seguente utilizza 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
}

L'esempio seguente utilizza 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
}

Ricevi asset

Dopo aver creato un asset, in genere lo leggi e lo estrai dall'altro lato della connessione. L'esempio seguente mostra come implementare il callback per rilevare una modifica dell'asset ed estrarlo:

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

Per saperne di più, consulta il progetto di esempio DataLayer su GitHub.