Sincronizza dati

Questo documento descrive come sincronizzare i dati tra un dispositivo Wear OS e uno smartphone. Consulta le linee guida di panoramica per sapere quando utilizzare l'API Data Layer e quando utilizzare la tua infrastruttura.

Inviare e sincronizzare i dati direttamente dalla rete

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

Sincronizzare i dati utilizzando l'API Data Layer di Wear OS

Un DataClient espone un'API per i componenti per leggere o scrivere in un DataItem o Asset.

È possibile impostare elementi dati e asset senza essere connessi ad 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 in 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.

Ascoltare gli eventi nei servizi

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

Ascoltare 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: 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

Sincronizzare 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. Tuttavia, se lo scambio è una tantum tra due dispositivi connessi, valuta se un trasferimento diretto più semplice è più appropriato.

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

Per questo motivo, non utilizzare l'API Data Layer come metodo principale per comunicare con una rete. Segui invece lo stesso pattern nella tua app per Wear OS come in un'app per smartphone, 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 evitare la ritrasmissione e per conservare la larghezza di banda Bluetooth. Un pattern comune è che un'app Telefono scarichi un'immagine, la riduca a una dimensione appropriata per la visualizzazione sull'orologio e la condivida con l'app dell'orologio come asset. Gli esempi seguenti illustrano questo pattern.

Trasferire un asset

Crea l'asset utilizzando uno dei create...() metodi nella Asset classe. 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 putAsset() metodo in DataMap o PutDataRequest. Quindi inserisci l'elemento dati nel datastore utilizzando il putDataItem() metodo, 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
}

Ricevere asset

Dopo aver creato un asset, in genere lo leggi ed estrai dall'altra parte della connessione. L'esempio seguente mostra come implementare il callback per rilevare una modifica dell'asset ed estrarre l'asset:

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.