Wear OS-Daten auf ein neues Mobilgerät übertragen

Wenn Nutzer ein Wear OS-Gerät einrichten, verbinden sie es mit einem bestimmten Mobilgerät. Später entscheidet sich der Nutzer möglicherweise für ein neues Mobilgerät und verbindet sein vorhandenes Wear OS-Gerät mit diesem neuen Mobilgerät. Einige Daten zu einem Wear OS-Gerät werden auf dem aktuell verbundenen Mobilgerät gespeichert.

Wenn Nutzer ab Wear OS 4 eine Verbindung zu einem neuen Mobilgerät herstellen, können sie Wear OS-Daten auf das neue Mobilgerät übertragen. Die Daten werden bei der Übertragung automatisch synchronisiert.

Wenn der Nutzer eine Übertragung anfordert, sendet die Wearable-Datenschicht DataItem-Objekte, die ursprünglich auf einem Mobilgerät gespeichert waren, an das andere Mobilgerät. Dies ermöglicht eine nahtlose Nutzung Ihrer App.

In diesem Dokument wird beschrieben, wie du deine Wear OS-App und die zugehörige mobile App für dieses Szenario konfigurieren kannst.

Vorbereitung

Bei der Datenübertragung werden DataItem-Objekte unterschiedlich verarbeitet, je nachdem, zu welcher Anwendung die Daten gehören:

Objekte, die der Wear OS App gehören
Diese Objekte bleiben auf dem Wear OS-Gerät erhalten.
Objekte, die der mobilen App gehören

Diese Objekte sind auf dem alten Gerät archiviert. Das System verpackt die archivierten Daten dann in ein DataItemBuffer-Objekt und sendet diese Daten an die mobile App, die auf dem neuen Mobilgerät installiert ist.

Sofort nach der Bereitstellung des Archivs ruft die Wearable-Datenschicht den onDataChanged()-Listener auf, ähnlich wie Ihre App benachrichtigt wird, wenn Daten vom Wear OS-Gerät geschrieben werden.

Übertragene Daten beibehalten

Es liegt in der Verantwortung deiner App, die übertragenen DataItem-Objekte beizubehalten. Kurz nach der Übermittlung der Daten an das neue Mobilgerät wird das Archiv auf dem alten Gerät gelöscht.

Jede der folgenden Bedingungen muss erfüllt sein:

  1. Ihre App ist auf beiden Mobilgeräten installiert, die an der Übertragung beteiligt sind.
  2. Die mobilen Apps, die auf jedem Mobilgerät installiert sind, haben entsprechende Paketsignaturen.

Andernfalls werden die archivierten DataItem-Objekte nicht zugestellt und stattdessen verworfen.

Daten vom alten Mobilgerät empfangen

Um auf dem neuen Mobilgerät Daten zu empfangen, die auf dem alten Mobilgerät archiviert wurden, muss die mobile App den onNodeMigrated()-Callback implementieren, der zur Klasse WearableListenerService gehört. Führe dazu die folgenden Schritte aus:

  1. Füge in die Build-Datei deiner mobilen App eine Abhängigkeit von der neuesten Version der Wearable-Bibliothek in den Google Play-Diensten ein:

    dependencies {
        ...
        implementation 'com.google.android.gms:play-services-wearable:18.1.0'
    }
    
  2. Deklarieren und exportieren Sie WearableListenerService in der Manifestdatei Ihrer App:

    <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>
    
  3. Erstellen Sie eine Dienstklasse, die WearableListenerService erweitert und onNodeMigrated() überschreibt.

    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();
        }
    }