Podczas konfigurowania urządzenia z Wear OS użytkownicy łączą je z konkretnym urządzeniem mobilnym. Użytkownik może później kupić nowe urządzenie mobilne i połączyć istniejące urządzenie z Wear OS z nowym urządzeniem mobilnym. Niektóre dane związane z urządzeniem z Wear OS są przechowywane na połączonym obecnie urządzeniu mobilnym.
Od Wear OS 4 użytkownicy, którzy łączą się z nowym urządzeniem mobilnym, mogą przenieść na nie dane z Wear OS. Dane są synchronizowane automatycznie po przeniesieniu.
Gdy użytkownik poprosi o przeniesienie, warstwa danych do noszenia dostarcza na inne urządzenie mobilne obiekty DataItem
, które były pierwotnie zapisane na jednym urządzeniu mobilnym. Dzięki temu użytkownicy mogą bez trudu korzystać z Twojej aplikacji.
Z tego dokumentu dowiesz się, jak skonfigurować aplikację na Wear OS i jej towarzyszącą aplikację mobilną pod kątem obsługi takiego scenariusza.
Przygotowanie
Proces przenoszenia danych obsługuje obiekty DataItem
w różny sposób, w zależności od tego, która aplikacja jest właścicielem danych:
- Obiekty należące do aplikacji na Wear OS
- Te obiekty są zachowywane na urządzeniu z Wear OS.
- Obiekty należące do aplikacji mobilnej
Te obiekty są zarchiwizowane na starym urządzeniu. System następnie spakuje zarchiwizowane dane do obiektu
DataItemBuffer
i dostarcza je do aplikacji mobilnej zainstalowanej na nowym urządzeniu.Bezpośrednio po dostarczeniu archiwum warstwa danych do noszenia wywołuje detektor
onDataChanged()
, podobnie jak aplikacja jest powiadamiana o zapisaniu danych przez urządzenie z Wear OS.
Zachowaj przeniesione dane
Za zachowanie przeniesionych obiektów DataItem
odpowiada Twoja aplikacja.
W krótkim czasie po dostarczeniu danych na nowe urządzenie mobilne archiwum jest usuwane ze starego urządzenia.
Upewnij się, że każdy z tych warunków jest spełniony:
- Aplikacja jest instalowana na obu urządzeniach mobilnych uwzględnionych w przenoszeniu.
- Aplikacje mobilne zainstalowane na poszczególnych urządzeniach mobilnych mają pasujące podpisy pakietów.
W przeciwnym razie zarchiwizowane obiekty DataItem
nie są dostarczane i zamiast tego są odrzucane.
Odbieranie danych ze starego urządzenia mobilnego
Aby można było odbierać dane na nowym urządzeniu mobilnym, które zostało zarchiwizowane na starym urządzeniu, Twoja aplikacja musi implementować wywołanie zwrotne onNodeMigrated()
, które jest częścią klasy WearableListenerService
. Aby to zrobić, wykonaj te czynności:
W pliku kompilacji aplikacji mobilnej dodaj zależność od najnowszej wersji biblioteki do noszenia w Usługach Google Play:
dependencies { ... implementation 'com.google.android.gms:play-services-wearable:18.1.0' }
Zadeklaruj i wyeksportuj
WearableListenerService
w pliku manifestu aplikacji:<service android:name=".MyWearableListenerService" android:exported="true"> <intent-filter> ... <action android:name="com.google.android.gms.wearable.NODE_MIGRATED" /> <data android:scheme="wear" /> </intent-filter> </service>
Utwórz klasę usługi, która rozszerza zakres
WearableListenerService
i zastępujeonNodeMigrated()
.Kotlin
class MyWearableListenerService : WearableListenerService() { val dataClient: DataClient = Wearable.getDataClient(this) private fun shouldHandleDataItem(nodeId: String, dataItem: DataItem): Boolean { // Your logic here return dataItem.uri.path?.startsWith("/my_feature_path/") == true } private suspend fun handleDataItem(nodeId: String, dataItem: DataItem) { val data = dataItem.data ?: return val path = dataItem.uri.path ?: return // Your logic here if (data.toString().startsWith("Please restore")) { dataClient.putDataItem( PutDataRequest.create(path).setData(data)) } } override fun onNodeMigrated(nodeId: String, archive: DataItemBuffer) { val dataItemsToHandle = mutableListOf<DataItem>() for (dataItem in archive) { if (shouldHandleDataItem(nodeId, dataItem)) { dataItemsToHandle.add(dataItem.freeze()) } } CoroutineScope(Job() + Dispatchers.IO).launch { for (dataItem in dataItemsToHandle) { handleDataItem(nodeId, dataItem) } } } }
Java
public class MyWearableListenerService extends WearableListenerService { private final DataClient dataClient = Wearable.getDataClient(this); private boolean shouldHandleDataItem(String nodeId, DataItem dataItem) { // Your logic here return Objects.requireNonNull(dataItem.getUri().getPath()) .startsWith("/my_feature_path/"); } private void handleDataItem(String nodeId, DataItem dataItem) { byte[] data = dataItem.getData(); String path = dataItem.getUri().getPath(); // Your logic here if (data != null && path != null && Arrays.toString(data) .startsWith("Please restore")) { assert path != null; dataClient.putDataItem( PutDataRequest.create(path).setData(data)); } } @Override public void onNodeMigrated(@NonNull String nodeId, DataItemBuffer archive) { List<DataItem> dataItemsToHandle = new ArrayList<>(); for (DataItem dataItem : archive) { if (shouldHandleDataItem(nodeId, dataItem)) { dataItemsToHandle.add(dataItem.freeze()); } } Thread thread = new Thread(() -> { for (DataItem dataItem : dataItemsToHandle) { handleDataItem(nodeId, dataItem); } }); thread.start(); } }