W tym dokumencie opisano, jak synchronizować dane między urządzeniem z Wear OS a telefonem. Zapoznaj się z ogólnymi wskazówkami, aby dowiedzieć się, kiedy używać interfejsu Data Layer API, a kiedy własnej infrastruktury.
Wysyłanie i synchronizowanie danych bezpośrednio z sieci
Twórz aplikacje na Wear OS, które komunikują się bezpośrednio z siecią. Używaj tych samych interfejsów API, których używasz do tworzenia aplikacji mobilnych, ale pamiętaj o pewnych różnicach dotyczących Wear OS.
Synchronizowanie danych za pomocą interfejsu Wear OS Data Layer API
DataClient udostępnia interfejs API, który umożliwia komponentom odczytywanie i zapisywanie danych w DataItem lub Asset.
Można ustawić elementy danych i zasoby, gdy nie ma połączenia z żadnymi urządzeniami. Są one synchronizowane, gdy urządzenia nawiążą połączenie sieciowe. Te dane są prywatne dla Twojej aplikacji i są dostępne tylko dla niej na innych urządzeniach.
DataItemjest synchronizowana na wszystkich urządzeniach w sieci Wear OS. Zwykle są niewielkie.Użyj
Asset, aby przesłać większy obiekt, np. obraz. System śledzi, które zasoby zostały już przeniesione, i automatycznie usuwa duplikaty.
Nasłuchiwanie zdarzeń w usługach
Rozszerz klasę WearableListenerService. System zarządza cyklem życia bazy WearableListenerService, wiążąc ją z usługą, gdy musi wysłać elementy danych lub wiadomości, i odłączając ją, gdy nie jest potrzebna.
Nasłuchiwanie zdarzeń w aktywnościach
Zaimplementuj interfejs OnDataChangedListener. Użyj tego interfejsu zamiast WearableListenerService, jeśli chcesz nasłuchiwać zmian tylko wtedy, gdy użytkownik aktywnie korzysta z aplikacji.
description: Przesyłaj duże obiekty binarne, takie jak obrazy, między telefonami z Androidem a zegarkami z Wear OS, korzystając z zasobów w interfejsie Data Layer API. keywords_public: Wear OS, Data Layer API, zasoby, przesyłanie danych przez Bluetooth, synchronizacja danych, DataMap, PutDataRequest
Synchronizowanie danych
Aby udostępniać duże obiekty binarne przez Bluetooth, np. nagranie głosowe z innego urządzenia, możesz dołączyć Asset do elementu danych, a następnie umieścić element danych w zreplikowanym magazynie danych.
Uwaga: interfejs Data Layer API może wysyłać wiadomości i synchronizować dane tylko z telefonami z Androidem lub zegarkami z Wear OS. Jeśli urządzenie z Wear OS jest sparowane z urządzeniem z iOS, interfejs Data Layer API nie będzie działać.
Z tego powodu nie używaj interfejsu Data Layer API jako głównego sposobu komunikacji z siecią. Zamiast tego postępuj zgodnie z tym samym wzorcem w aplikacji na Wear OS co w aplikacji na telefon – z pewnymi niewielkimi różnicami, które opisano w artykule Dostęp do sieci i synchronizacja na Wear OS.
Zasoby automatycznie obsługują buforowanie danych, aby zapobiec ponownej transmisji i oszczędzać przepustowość Bluetootha. Typowy wzorzec polega na tym, że aplikacja na telefon pobiera obraz, zmniejsza go do rozmiaru odpowiedniego do wyświetlenia na zegarku i udostępnia go aplikacji na zegarek jako zasób. Poniższe przykłady ilustrują ten wzorzec.
Przenoszenie zasobu
Utwórz zasób, korzystając z jednej z metod create...() w klasie Asset. Przekonwertuj bitmapę na tablicę bajtów, a następnie wywołaj metodę createFromBytes(), aby utworzyć komponent, jak pokazano w tym przykładzie.
private fun createAssetFromBitmap(bitmap: Bitmap): Asset = ByteArrayOutputStream().let { byteStream -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream) Asset.createFromBytes(byteStream.toByteArray()) }
Następnie dołącz zasób do elementu danych za pomocą metody putAsset() w DataMap lub PutDataRequest. Następnie umieść element danych w magazynie danych za pomocą metody putDataItem(), jak pokazano w poniższych przykładach.
W tym przykładzie użyto 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 }
W tym przykładzie użyto 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 }
Odbieranie zasobów
Po utworzeniu zasobu zwykle odczytujesz go i wyodrębniasz po drugiej stronie połączenia. Poniższy przykład pokazuje, jak zaimplementować wywołanie zwrotne, aby wykryć zmianę komponentu i wyodrębnić go:
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 } }
Więcej informacji znajdziesz w przykładowym projekcie DataLayer na GitHubie.