DataItem
definiuje interfejs używany przez system do synchronizowania danych między urządzeniami mobilnymi i urządzeniami do noszenia. DataItem
zazwyczaj składa się z tych komponentów:
- Ładunek: tablica bajtów, którą możesz ustawić za pomocą danych, co umożliwia własną serializację i deserializację obiektów. Rozmiar ładunku jest ograniczony do 100 KB.
-
Ścieżka: unikalny ciąg znaków, który musi zaczynać się od ukośnika, np.
"/path/to/data"
.
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 Twoje urządzenie z Wear OS jest sparowane z urządzeniem z iOS, interfejs Data Layer API nie będzie działać.
W związku z tym interfejs Data Layer API nie powinien być podstawowym sposobem komunikacji z siecią. Zamiast tego stosuj
ten sam wzór co w przypadku aplikacji mobilnej, z kilkoma drobnymi różnicami.
Zwykle nie implementujesz DataItem
bezpośrednio. Zamiast tego:
-
Utwórz obiekt
PutDataRequest
, podając ścieżkę ciągu tekstowego, aby jednoznacznie zidentyfikować element. -
Wywołaj
setData()
, aby ustawić ładunek. -
Jeśli opóźnienie synchronizacji negatywnie wpływa na wygodę użytkowników, wywołaj
setUrgent()
. -
Użyj metody
putDataItem
klasyDataClient
, aby poprosić system o utworzenie elementu danych.
Gdy żądasz elementów danych, system zwraca obiekty, które prawidłowo implementują interfejs DataItem
. Jednak zamiast korzystać z nieprzetworzonych bajtów za pomocą funkcji setData()
, zalecamy użycie mapy danych, która udostępnia element danych za pomocą interfejsu podobnego do Bundle
.
Więcej informacji znajdziesz w aplikacji DataLayer Sample.
Synchronizacja danych z mapą danych
W miarę możliwości używaj klasy
DataMap
.
To podejście umożliwia pracę z elementami danych w postaci Bundle
Androida, dzięki czemu system wykonuje serializację i deserializację obiektów za Ciebie, a możesz manipulować danymi za pomocą par klucz-wartość.
Aby użyć mapy danych:
-
Utwórz obiekt
PutDataMapRequest
, aby ustawić ścieżkę elementu danych.Uwaga: ciąg znaków to unikalny identyfikator elementu danych, który umożliwia dostęp do niego z obu stron połączenia. Ścieżka musi zaczynać się od ukośnika. Jeśli w aplikacji używasz danych hierarchicznych, utwórz schemat ścieżki pasujący do struktury danych.
-
Wywołaj
PutDataMapRequest.getDataMap()
, aby uzyskać mapę danych, dla której możesz ustawiać wartości. -
Ustaw wartości na potrzeby mapowania danych za pomocą metod
put...()
, takich jakputString()
. -
Jeśli opóźnienie synchronizacji negatywnie wpływa na wygodę użytkowników, wywołaj
setUrgent()
. -
Wywołaj
PutDataMapRequest.asPutDataRequest()
, aby uzyskać obiektPutDataRequest
. -
Użyj metody
putDataItem
klasyDataClient
, aby poprosić system o utworzenie elementu danych.Uwaga: jeśli słuchawka i urządzenia do noszenia nie są rozłączone, dane są buforowane i zsynchronizowane po ponownym nawiązaniu połączenia.
Metoda increaseCounter()
w poniższym przykładzie pokazuje, jak utworzyć mapę danych i umieścić w niej dane:
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity() { private lateinit var dataClient: DataClient private var count = 0 ... // Create a data map and put data in it private fun increaseCounter() { val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { dataMap.putInt(COUNT_KEY, count++) asPutDataRequest() } val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq) } ... }
Java
public class MainActivity extends Activity { private static final String COUNT_KEY = "com.example.key.count"; private DataClient dataClient; private int count = 0; ... // Create a data map and put data in it private void increaseCounter() { PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count"); putDataMapReq.getDataMap().putInt(COUNT_KEY, count++); PutDataRequest putDataReq = putDataMapReq.asPutDataRequest(); Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq); } ... }
Więcej informacji o obsłudze obiektu
Tasks
znajdziesz w
dokumentacji referencyjnej.
Ustawianie priorytetu elementu DataItem
Interfejs API
DataClient
umożliwia pilne wysyłanie żądań synchronizacji obiektów DataItem
.
Zwykle system opóźnia dostarczanie elementów danych do sieci Wear OS, aby wydłużyć czas pracy urządzeń użytkowników na baterii, ale jeśli opóźnienie synchronizacji elementów danych negatywnie wpływa na wygodę użytkowników, możesz oznaczyć je jako pilne. Na przykład w przypadku aplikacji do zdalnego sterowania, w której użytkownik oczekuje, że jego działania zostaną natychmiast odzwierciedlone, system może natychmiast zsynchronizować elementy danych, wywołując metodę
setUrgent()
.
Jeśli nie zadzwonisz pod numer setUrgent()
, system może opóźnić synchronizację mniej pilnych elementów danych nawet po 30 minutach. Zazwyczaj opóźnienie wynosi tylko kilka minut. Domyślna pilna czynność nie jest pilna, więc jeśli chcesz zachować natychmiastowe działanie synchronizacji z poprzednich wersji interfejsu Wear OS API, użyj setUrgent()
.
Wykrywa zdarzenia związane z elementem danych
Jeśli jedna strona połączenia warstwy danych zmienia element danych, powiadom użytkownika o wszelkich zmianach po drugiej stronie połączenia. Aby to zrobić, zaimplementuj odbiornik zdarzenia elementu danych.
Fragment kodu w poniższym przykładzie powiadamia aplikację o zmianie wartości licznika zdefiniowanej w poprzednim przykładzie:
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener { private var count = 0 override fun onResume() { super.onResume() Wearable.getDataClient(this).addListener(this) } override fun onPause() { super.onPause() Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> // DataItem changed if (event.type == DataEvent.TYPE_CHANGED) { event.dataItem.also { item -> if (item.uri.path.compareTo("/count") == 0) { DataMapItem.fromDataItem(item).dataMap.apply { updateCount(getInt(COUNT_KEY)) } } } } else if (event.type == DataEvent.TYPE_DELETED) { // DataItem deleted } } } // Method to update the count private fun updateCount(int: Int) { ... } ... }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { private static final String COUNT_KEY = "com.example.key.count"; private int count = 0; @Override protected void onResume() { super.onResume(); Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { super.onPause(); Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED) { // DataItem changed DataItem item = event.getDataItem(); if (item.getUri().getPath().compareTo("/count") == 0) { DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap(); updateCount(dataMap.getInt(COUNT_KEY)); } } else if (event.getType() == DataEvent.TYPE_DELETED) { // DataItem deleted } } } // Method to update the count private void updateCount(int c) { ... } ... }
To działanie implementuje interfejs
DataClient.OnDataChangedListener
. Aktywność dodaje się jako odbiornik zdarzeń elementu danych w metodzie onResume()
i usuwa go w metodzie onPause()
. Aby zobaczyć implementację z użyciem obrazów oraz modele i usługi, otwórz aplikację DataLayer Sample (Przykład warstwy danych).
Możesz też zaimplementować detektor jako usługę. Więcej informacji znajdziesz w artykule Nasłuchiwanie zdarzeń warstwy danych.