Podczas konfigurowania urządzenia z Wear OS użytkownik łączy je z konkretnym urządzeniem mobilnym. Użytkownik może później zakupić nowe urządzenie mobilne i połączyć z nim dotychczasowe urządzenie z Wear OS. Niektóre dane związane z urządzeniem z Wear OS są przechowywane na obecnie połączonym urządzeniu mobilnym.
Od Wear OS 4 użytkownicy po połączeniu się z nowym urządzeniem mobilnym mogą przenieść na nie dane z Wear OS. Dane są synchronizowane automatycznie.
Gdy użytkownik poprosi o przeniesienie, warstwa danych do noszenia dostarcza obiekty DataItem
pierwotnie zapisane na jednym urządzeniu mobilnym na drugie. Dzięki temu użytkownicy aplikacji będą mogli bez trudu korzystać z niej.
Z tego dokumentu dowiesz się, jak skonfigurować aplikację na Wear OS i jej towarzyszącą aplikację mobilną, aby spełnić ten scenariusz.
Przygotowanie
Proces przenoszenia danych obsługuje obiekty DataItem
w różny sposób, w zależności od tego, do której aplikacji należą dane:
- 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. Następnie system pakuje zarchiwizowane dane do obiektu
DataItemBuffer
i dostarcza je do aplikacji mobilnej zainstalowanej na nowym urządzeniu mobilnym.Bezpośrednio po dostarczeniu archiwum warstwa danych do noszenia wywołuje detektor
onDataChanged()
, podobnie jak aplikacja jest powiadamiana o zapisywaniu danych przez urządzenie z Wear OS.
Zachowaj przesłane dane
Obowiązkiem Twojej aplikacji jest zachowanie przeniesionych obiektów DataItem
.
Krótko 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:
- Twoja aplikacja jest zainstalowana na obu urządzeniach mobilnych objętych przenoszeniem.
- Aplikacje mobilne zainstalowane na każdym urządzeniu mobilnym mają pasujące podpisy pakietów.
W przeciwnym razie zarchiwizowane obiekty DataItem
nie zostaną dostarczone i zostaną odrzucone.
Odbieraj dane 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, aplikacja mobilna musi wdrożyć wywołanie zwrotne onNodeMigrated()
, które jest częścią klasy WearableListenerService
. Aby to zrobić:
W pliku kompilacji aplikacji mobilnej umieść zależność od najnowszej wersji biblioteki do noszenia w Usługach Google Play:
dependencies { ... implementation 'com.google.android.gms:play-services-wearable:18.2.0' }
Zadeklaruj i wyeksportuj element
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(); } }