Ce document explique comment synchroniser des données entre un appareil Wear OS et un portable.
Envoyer et synchroniser des données directement à partir du réseau
Créez des applications Wear OS pour communiquer directement avec le réseau. Utiliser la même les API que vous utilisez pour le développement mobile, mais qui conservent des exigences spécifiques à Wear OS ; à l'esprit les différences.
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 dans un DataItem
ou
Asset
Il est possible de définir des éléments de données et des éléments sans être connecté à aucun appareil. Ils sont synchronisés lorsque les appareils établissent une connexion réseau. Ces données est privée et n'est accessible 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, comme une image. Le système effectue le suivi des éléments 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
cycle de vie du WearableListenerService
de base, qui est lié au service
doit envoyer des éléments de données ou des messages et annuler le lien avec le service en l'absence de travail
nécessaires.
Écouter les événements dans les activités
Implémentez l'interface OnDataChangedListener
. Utilisez plutôt cette interface
d'un WearableListenerService
lorsque vous souhaitez écouter les modifications uniquement lorsque
utilise activement votre application.
Transférer des données
Pour envoyer des objets binaires volumineux via le transport Bluetooth, tels qu'un enregistrement vocal
depuis un autre appareil, vous pouvez connecter
<ph type="x-smartling-placeholder"></ph>
Asset
à un élément de données, puis placer cet élément dans le datastore répliqué.
Les éléments gèrent automatiquement la mise en cache des données pour empêcher la retransmission et préserver la bande passante Bluetooth. Il est courant de télécharger une image, de la réduire à une taille appropriée pour l'afficher sur l'objet connecté et de la transmettre à l'application connectée en tant qu'élément. Les exemples suivants illustrent ce schéma.
Remarque : Bien que la taille des éléments de données soit théoriquement limitée à 100 Ko, en pratique, vous pouvez utiliser des éléments de données plus volumineux. Pour les éléments de données plus volumineux, séparez les données par des chemins uniques et éviter d'utiliser un seul chemin pour toutes les données. Dans de nombreux cas, le transfert d'éléments volumineux affecte l'expérience utilisateur. Par conséquent, testez vos applications pour vous assurer qu'elles fonctionnent bien lors de ce type de transfert.
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 flux d'octets, puis appelez createFromBytes()
pour créer l'élément, comme illustré dans l'exemple suivant.
Kotlin
private fun createAssetFromBitmap(bitmap: Bitmap): Asset = ByteArrayOutputStream().let { byteStream -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream) Asset.createFromBytes(byteStream.toByteArray()) }
Java
private static Asset createAssetFromBitmap(Bitmap bitmap) { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream); return Asset.createFromBytes(byteStream.toByteArray()); }
Associez ensuite cet élément à un élément de données avec la méthode putAsset()
dans DataMap
ou PutDataRequest
. Placez ensuite l'élément de données dans le magasin de données à l'aide de la méthode
<ph type="x-smartling-placeholder"></ph>
putDataItem()
, comme illustré dans les exemples suivants.
L'exemple suivant utilise PutDataRequest
:
Kotlin
val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap -> createAssetFromBitmap(bitmap) } val request: PutDataRequest = PutDataRequest.create("/image").apply { putAsset("profileImage", asset) } val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)
Java
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); Asset asset = createAssetFromBitmap(bitmap); PutDataRequest request = PutDataRequest.create("/image"); request.putAsset("profileImage", asset); Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);
L'exemple suivant utilise PutDataMapRequest
:
Kotlin
val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap -> createAssetFromBitmap(bitmap) } val request: PutDataRequest = PutDataMapRequest.create("/image").run { dataMap.putAsset("profileImage", asset) asPutDataRequest() } val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)
Java
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); Asset asset = createAssetFromBitmap(bitmap); PutDataMapRequest dataMap = PutDataMapRequest.create("/image"); dataMap.getDataMap().putAsset("profileImage", asset); PutDataRequest request = dataMap.asPutDataRequest(); Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);
Recevoir les éléments
Lorsqu'un élément est créé, vous souhaitez probablement le lire et l'extraire de l'autre côté de la connexion. Voici un exemple d'implémentation du rappel pour détecter une modification d'élément et l'extraire :
Kotlin
override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" } .forEach { event -> val bitmap: Bitmap? = DataMapItem.fromDataItem(event.dataItem) .dataMap.getAsset("profileImage") .let { asset -> loadBitmapFromAsset(asset) } // Do something with the bitmap } } fun loadBitmapFromAsset(asset: Asset): Bitmap? { // Convert asset into a file descriptor and block until it's ready val assetInputStream: InputStream? = Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset)) ?.inputStream return assetInputStream?.let { inputStream -> // Decode the stream into a bitmap BitmapFactory.decodeStream(inputStream) } ?: run { Log.w(TAG, "Requested an unknown Asset.") null } }
Java
@Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/image")) { DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage"); Bitmap bitmap = loadBitmapFromAsset(profileAsset); // Do something with the bitmap } } } public Bitmap loadBitmapFromAsset(Asset asset) { if (asset == null) { throw new IllegalArgumentException("Asset must be non-null"); } // Convert asset into a file descriptor and block until it's ready InputStream assetInputStream = Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset)) .getInputStream(); if (assetInputStream == null) { Log.w(TAG, "Requested an unknown Asset."); return null; } // Decode the stream into a bitmap return BitmapFactory.decodeStream(assetInputStream); }
Pour en savoir plus, consultez l'exemple de projet DataLayer sur GitHub.