Po wywołaniu interfejsu API warstwy danych możesz uzyskać statusu połączenia po jego zakończeniu. Możesz też nasłuchiwać zdarzeń dotyczących danych zmian danych wprowadzanych przez aplikację w dowolnym miejscu Sieć Wear OS by Google.
Przykłady efektywnej pracy z interfejsem API warstwy danych znajdziesz Android DataLayer Sample.
Oczekiwanie na stan wywołań warstwy danych
Wywołania interfejsu API warstwy danych, takie jak wywołanie interfejsu putDataItem
funkcji
DataClient
klasa – czasami zwraca błąd
Task<ResultType>
obiekt. Gdy tylko obiekt Task
zostanie utworzony operacja
dodano do kolejki w tle. Jeśli nie zrobisz nic więcej, operacja
a konkretnie zakończy się dyskretnie.
Zwykle jednak wolisz używać
wynik po jej zakończeniu, więc obiekt Task
pozwala
można zaczekać na stan wyniku, asynchronicznie lub synchronicznie.
Wywołania asynchroniczne
Jeśli Twój kod działa w głównym wątku UI, nie wysyłaj blokujących wywołań do
Interfejs API warstwy danych. Asynchroniczne uruchamianie wywołań przez dodanie metody wywołania zwrotnego
do obiektu Task
, który uruchamia się po zakończeniu operacji:
Kotlin
// Using Kotlin function references task.addOnSuccessListener(::handleDataItem) task.addOnFailureListener(::handleDataItemError) task.addOnCompleteListener(::handleTaskComplete) ... fun handleDataItem(dataItem: DataItem) { ... } fun handleDataItemError(exception: Exception) { ... } fun handleTaskComplete(task: Task<DataItem>) { ... }
Java
// Using Java 8 Lambdas. task.addOnSuccessListener(dataItem -> handleDataItem(dataItem)); task.addOnFailureListener(exception -> handleDataItemError(exception)); task.addOnCompleteListener(task -> handleTaskComplete(task));
Zobacz interfejsu Task API do innych możliwości, w tym do łańcucha wykonywania różne zadania.
Wywołania synchroniczne
Jeśli Twój kod działa w osobnym wątku modułu obsługi w usłudze w tle,
na przykład w
WearableListenerService
,
możesz blokować połączenia. W takim przypadku możesz zadzwonić pod numer Tasks.await()
w: Task
, który blokuje do czasu zakończenia żądania i zwraca
Result
obiekt. Widać to w przykładzie poniżej.
Uwaga: nie używaj tej opcji w wątku głównym.
Kotlin
try { Tasks.await(dataItemTask).apply { Log.d(TAG, "Data item set: $uri") } } catch (e: ExecutionException) { ... } catch (e: InterruptedException) { ... }
Java
try { DataItem item = Tasks.await(dataItemTask); Log.d(TAG, "Data item set: " + item.getUri()); } catch (ExecutionException | InterruptedException e) { ... }
Nasłuchuj zdarzeń warstwy danych
Warstwa danych synchronizuje i wysyła dane między urządzeniami urządzeń do noszenia, zwykle musisz nasłuchiwać ważnych zdarzeń, takich jak tworzone elementy danych i odbierane wiadomości.
Istnieją 2 sposoby nasłuchiwania zdarzeń warstwy danych:
- Utwórz usługę z rozszerzeniem
WearableListenerService
. - Utwórz działanie lub klasę, które implementują interfejs
DataClient.OnDataChangedListener
.
Korzystając z obu tych opcji, zastępujesz metody wywołania zwrotnego zdarzenia danych dla funkcji zdarzenia, które chcesz obsługiwać.
Uwaga: przy wyborze bierz pod uwagę zużycie baterii przez aplikację
w implementacji detektora. WearableListenerService
jest zarejestrowany w pliku manifestu aplikacji i może ją uruchomić, jeśli jeszcze nie jest włączona;
w domu. Jeśli chcesz nasłuchiwać tylko zdarzeń, gdy aplikacja jest już uruchomiona,
co często ma miejsce w przypadku aplikacji interaktywnych, nie używaj
WearableListenerService
Zamiast tego zarejestruj detektora na żywo.
Na przykład użyj metody addListener
funkcji DataClient
zajęcia. Może to zmniejszyć obciążenie systemu i wykorzystanie baterii.
Używanie usługi WearableListenerService
Zazwyczaj tworzysz instancje
WearableListenerService
zarówno na urządzeniu do noszenia,
na urządzenia przenośne. Jeśli jednak nie interesują Cię zdarzenia związane z danymi w jednej z
aplikacji, nie musisz implementować w niej tej usługi.
Możesz na przykład mieć aplikację podręczną, która ustawia i pobiera obiekty danych. i aplikacji do noszenia, która nasłuchuje aktualizacji, aby aktualizować interfejs. aplikacja do noszenia nigdy nie aktualizuje żadnych danych, więc nie będzie nasłuchiwać zdarzeń danych z aplikacji do noszenia.
Niektóre zdarzenia, których możesz nasłuchiwać za pomocą
WearableListenerService
to:
-
onDataChanged()
: za każdym razem, gdy obiekt elementu danych zostaje utworzony, usunięty lub zmieniony, to wywołanie zwrotne we wszystkich połączonych węzłach. -
onMessageReceived()
: komunikat wysłany z aktywatorów węzła wywołanie zwrotne w węźle docelowym. -
onCapabilityChanged()
: gdy dostępna jest funkcja reklamowana w konkretnej aplikacji. w sieci, zdarzenie aktywuje to wywołanie zwrotne. Jeśli szukasz w pobliżu węzła, możesz wysłać zapytanie MetodaisNearby()
węzłów podanych w wywołaniu zwrotnym.
Możesz też nasłuchiwać zdarzeń z
ChannelClient.ChannelCallback
, na przykład onChannelOpened()
.
Wszystkie poprzednie zdarzenia są wykonywane w wątku w tle, a nie w głównym wątku.
Aby utworzyć WearableListenerService
, wykonaj te czynności:
- Utwórz zajęcia z rozszerzeniem
WearableListenerService
. - Wykrywaj zdarzenia, które Cię interesują, np.
onDataChanged()
. - Zadeklaruj filtr intencji w pliku manifestu Androida, aby powiadamiać system o
WearableListenerService
Ta deklaracja umożliwia systemowi powiązanie w razie potrzeby.
Poniższy przykład pokazuje, jak wdrożyć prostą WearableListenerService
:
Kotlin
private const val TAG = "DataLayerSample" private const val START_ACTIVITY_PATH = "/start-activity" private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received" class DataLayerListenerService : WearableListenerService() { override fun onDataChanged(dataEvents: DataEventBuffer) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: $dataEvents") } // Loop through the events and send a message // to the node that created the data item. dataEvents.map { it.dataItem.uri } .forEach { uri -> // Get the node ID from the host value of the URI. val nodeId: String = uri.host // Set the data of the message to be the bytes of the URI. val payload: ByteArray = uri.toString().toByteArray() // Send the RPC. Wearable.getMessageClient(this) .sendMessage(nodeId, DATA_ITEM_RECEIVED_PATH, payload) } } }
Java
public class DataLayerListenerService extends WearableListenerService { private static final String TAG = "DataLayerSample"; private static final String START_ACTIVITY_PATH = "/start-activity"; private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received"; @Override public void onDataChanged(DataEventBuffer dataEvents) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: " + dataEvents); } // Loop through the events and send a message // to the node that created the data item. for (DataEvent event : dataEvents) { Uri uri = event.getDataItem().getUri(); // Get the node ID from the host value of the URI. String nodeId = uri.getHost(); // Set the data of the message to be the bytes of the URI. byte[] payload = uri.toString().getBytes(); // Send the RPC. Wearable.getMessageClient(this).sendMessage( nodeId, DATA_ITEM_RECEIVED_PATH, payload); } } }
Z sekcji poniżej dowiesz się, jak używać w przypadku tego detektora filtra intencji.
Używanie filtrów w usłudze WearableListenerService
Filtr intencji dla przykładu elementu WearableListenerService
widocznego w poprzedniej sekcji
może wyglądać tak:
<service android:name=".DataLayerListenerService" android:exported="true" tools:ignore="ExportedService" > <intent-filter> <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> <data android:scheme="wear" android:host="*" android:path="/start-activity" /> </intent-filter> </service>
W tym filtrze działanie DATA_CHANGED
zastępuje
zalecane wcześniej działanie BIND_LISTENER
, tak aby tylko określone
zdarzeń powodują wybudzenie lub uruchomienie aplikacji. Ta zmiana poprawia wydajność systemu
oraz zmniejsza zużycie baterii i inne koszty związane z
. W tym przykładzie zegarek nasłuchuje
/start-activity
elementu danych oraz
Telefon nasłuchuje odpowiedzi na wiadomość /data-item-received
.
Obowiązują standardowe reguły dopasowania filtra Androida. Możesz określić wiele usług
na plik manifestu, wiele filtrów intencji na usługę, wiele działań na filtr,
oraz wiele streszczeń danych na filtr. Filtry mogą działać na hoście z symbolem wieloznacznym lub być włączone
konkretnego filmu. Aby dopasować do hosta z symbolem wieloznacznym, użyj host="*"
. Aby dopasować
na konkretnym hoście, wpisz host=<node_id>
.
Możesz też dopasować ścieżkę literału lub prefiks ścieżki. Aby to zrobić: musisz podać symbol wieloznaczny lub konkretny host. W przeciwnym razie system zignoruje podaną ścieżkę.
Więcej informacji o typach filtrów obsługiwanych przez Wear OS znajdziesz w
Dokumentacja interfejsu API dla usługi
WearableListenerService
Więcej informacji o filtrach danych i regułach dopasowania znajdziesz w dokumentacji interfejsu API
dokumentacja: <data>
manifestu.
Dopasowując filtry intencji, pamiętaj o 2 ważnych regułach:
- Jeśli nie określisz schematu dla filtra intencji, system go zignoruje. wszystkich pozostałych atrybutów URI.
- Jeśli nie określono hosta dla filtra, system ignoruje wszystkich atrybutów ścieżki.
Korzystanie z detektora na żywo
Jeśli Twojej aplikacji interesują się tylko zdarzenia warstwy danych, gdy użytkownik wchodzi w interakcję z: aplikacji, może nie potrzebować długoterminowej usługi do obsługi każdej zmiany danych. W możesz nasłuchiwać zdarzeń w działaniu, implementując jeden lub inne interfejsy:
DataClient.OnDataChangedListener
MessageClient.OnMessageReceivedListener
CapabilityClient.OnCapabilityChangedListener
ChannelClient.ChannelCallback
Aby utworzyć działanie, które nasłuchuje zdarzeń związanych z danymi:
- Zaimplementuj odpowiednie interfejsy.
- W metodzie
onCreate()
lubonResume()
wywołaj funkcjęWearable.getDataClient(this).addListener()
,MessageClient.addListener()
,CapabilityClient.addListener()
lubChannelClient.registerChannelCallback()
, aby powiadomić Google Play usług, w których Twoja aktywność chce nasłuchiwać zdarzeń warstwy danych. - W:
onStop()
lubonPause()
, wyrejestruj wszystkich detektorów zDataClient.removeListener()
,MessageClient.removeListener()
,CapabilityClient.removeListener()
lubChannelClient.unregisterChannelCallback()
. - Jeśli aktywność obejmuje tylko zdarzenia z określonym prefiksem ścieżki, może dodać detektor z odpowiednim filtrem prefiksu, aby odbierać tylko dane, które są w odniesieniu do bieżącego stanu aplikacji.
- Wdróż
onDataChanged()
,onMessageReceived()
,onCapabilityChanged()
lub metod zChannelClient.ChannelCallback
, w zależności od zaimplementowanych interfejsów. Te metody są wywoływane w wątku głównym lub określić niestandardowy obiektLooper
za pomocąWearableOptions
.
Oto przykład implementującej właściwość DataClient.OnDataChangedListener
:
Kotlin
class MainActivity : Activity(), DataClient.OnDataChangedListener { public override fun onResume() { Wearable.getDataClient(this).addListener(this) } override fun onPause() { Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> if (event.type == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.dataItem.uri) } else if (event.type == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.dataItem.uri) } } } }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { @Override public void onResume() { Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri()); } else if (event.getType() == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri()); } } } }
Korzystanie z filtrów w przypadku słuchaczy na żywo
Jak już wspomnieliśmy, tak samo jak możesz określić filtry intencji
oparte na pliku manifestu WearableListenerService
obiektów, możesz użyć filtrów intencji podczas rejestrowania detektora
Do noszenia
API. Te same reguły dotyczą zarówno detektorów transmisji na żywo opartych na interfejsie API,
detektorów opartych na plikach manifestu.
Typowym wzorcem jest rejestrowanie detektora z określoną ścieżką lub prefiksem ścieżki
w onResume()
aktywności
a następnie usuń detektora
Metoda onPause()
.
Taki sposób wdrożenia detektorów pozwala aplikacji bardziej wybiórczo
do odbierania zdarzeń, poprawiając jego wygląd i wydajność.