Synchroniser les données

Ce document explique comment synchroniser des données entre un appareil Wear OS et un téléphone. Consultez les conseils généraux pour savoir quand utiliser l'API Data Layer et quand utiliser votre infrastructure.

Envoyer et synchroniser des données directement à partir du réseau

Créez des applications Wear OS pour communiquer directement avec le réseau. Utilisez les mêmes API que pour le développement mobile, mais gardez à l'esprit certaines différences spécifiques à Wear OS.

Synchroniser des données à l'aide de l'API Wear OS Data Layer

Un DataClient expose une API pour que les composants puissent lire ou écrire un DataItem ou un Asset.

Il est possible de définir des éléments de données et des composants sans être connecté à des appareils. Ils sont synchronisés lorsque les appareils établissent une connexion réseau. Ces données sont privées pour votre application et ne sont accessibles qu'à votre application sur d'autres appareils.

  • Un DataItem est synchronisé sur tous les appareils d'un réseau Wear OS. Ils sont généralement de petite taille.

  • Utilisez un Asset pour transférer un objet plus volumineux, tel qu'une image. Le système garde la trace des composants qui ont déjà été transférés et effectue automatiquement la déduplication.

Écouter les événements dans les services

Étendez la classe WearableListenerService. Le système gère le cycle de vie du WearableListenerService de base en l'associant au service lorsqu'il doit envoyer des éléments de données ou des messages et en le dissociant en l'absence de travail.

Écouter les événements dans les activités

Implémenter l'interface OnDataChangedListener. Utilisez cette interface à la place d'un WearableListenerService lorsque vous souhaitez écouter les modifications uniquement lorsque l'utilisateur utilise activement votre application.

description: Transférez des objets binaires volumineux, tels que des images, entre des téléphones Android et des montres Wear OS à l'aide des éléments de l'API Data Layer. keywords_public: Wear OS, API Data Layer, Éléments, Transfert de données Bluetooth, Synchronisation des données, DataMap, PutDataRequest

Synchroniser les données

Pour partager des objets binaires volumineux via le transport Bluetooth, tels qu'un enregistrement vocal depuis un autre appareil, vous pouvez associer un Asset à un élément de données, puis placer l'élément de données dans le data store répliqué.

Remarque : L'API Data Layer ne peut envoyer des messages et synchroniser des données qu'avec des téléphones fonctionnant sous Android ou des montres Wear OS. Si un appareil Wear OS est associé à un appareil iOS, l'API Data Layer ne fonctionnera pas.

C'est pourquoi vous ne devez pas utiliser cette API comme moyen de communication principal avec un réseau. Suivez plutôt le même schéma dans votre application Wear OS que dans une application mobile, avec quelques différences mineures, comme décrit dans Accès au réseau et synchronisation sur Wear OS.

Les composants gèrent automatiquement la mise en cache des données pour éviter la retransmission et économiser la bande passante Bluetooth. Il est courant qu'une application de téléphone télécharge une image, la réduise à une taille appropriée pour l'afficher sur la montre et la partage avec l'application de la montre en tant qu'élément. Les exemples suivants illustrent ce schéma.

Transférer un élément

Créez l'élément à l'aide de l'une des méthodes create...() de la classe Asset. Convertissez un bitmap en tableau d'octets, puis appelez createFromBytes() pour créer l'élément, comme illustré dans l'exemple suivant.

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

Ensuite, associez l'élément à un élément de données à l'aide de la méthode putAsset() dans DataMap ou PutDataRequest. Ensuite, placez l'élément de données dans le datastore à l'aide de la méthode putDataItem(), comme indiqué dans les exemples suivants.

L'exemple suivant utilise 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'exemple suivant utilise 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
}

Recevoir les éléments

Une fois que vous avez créé un élément, vous le lisez et l'extrayez généralement de l'autre côté de la connexion. L'exemple suivant montre comment implémenter le rappel pour détecter une modification d'élément et l'extraire :

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

Pour en savoir plus, consultez l'exemple de projet DataLayer sur GitHub.