Как перенести данные Wear OS на новое мобильное устройство

Когда пользователи настраивают устройство Wear OS, они подключают его к определенному мобильному устройству. Пользователь может приобрести новое мобильное устройство и подключить к нему имеющееся устройство Wear OS. Некоторые данные, связанные с устройством Wear OS, хранятся на подключенном мобильном устройстве.

Начиная с Wear OS 4, при подключении к новому мобильному устройству пользователи могут переносить на него данные Wear OS. Данные синхронизируются автоматически при передаче.

Когда пользователь запрашивает передачу, уровень данных носимого устройства доставляет объекты DataItem, изначально сохраненные на одном мобильном устройстве, на другое мобильное устройство. Это позволяет пользователям вашего приложения без проблем переходить на сайт.

В этом документе рассказывается, как настроить приложение для Wear OS и его сопутствующее мобильное приложение для поддержки этого сценария.

Подготовка

Процесс переноса данных обрабатывает объекты DataItem по-разному в зависимости от того, какому приложению принадлежат данные:

Объекты, принадлежащие приложению для Wear OS
Эти объекты сохраняются на устройстве Wear OS.
объекты, принадлежащие мобильному приложению;

Эти объекты будут заархивированы на старом устройстве. Затем система упаковывает архивные данные в объект DataItemBuffer и передает их в мобильное приложение, установленное на новом мобильном устройстве.

Сразу после получения архива уровень данных Wearable вызывает слушателя onNodeMigrated(), как и в случае, когда устройство Wear OS записывает данные.

Как сохранить перенесенные данные

Приложение должно сохранять переданные объекты DataItem. Вскоре после того, как данные будут перенесены на новое мобильное устройство, архив будет удален со старого.

Убедитесь, что выполняются следующие условия:

  1. Приложение установлено на обоих мобильных устройствах, участвующих в передаче.
  2. У мобильных приложений, установленных на каждом мобильном устройстве, совпадают подписи пакетов.

В противном случае заархивированные объекты DataItem не будут доставлены и будут удалены.

Как получить данные со старого мобильного устройства

Чтобы получать на новом мобильном устройстве данные, заархивированные на старом, в мобильном приложении необходимо реализовать обратный вызов onNodeMigrated(), который является частью класса WearableListenerService. Для этого выполните следующие действия:

  1. В файл сборки мобильного приложения добавьте зависимость от последней версии библиотеки для носимых устройств в сервисах Google Play:

    dependencies {
        ...
        implementation 'com.google.android.gms:play-services-wearable:20.0.1'
    }
    
  2. Объявите и экспортируйте WearableListenerService в файле манифеста приложения:

    <service
        android:name=".snippets.datalayer.MyWearableListenerService"
        android:exported="true"
        tools:ignore="ExportedService">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.NODE_MIGRATED" />
            <data android:scheme="wear" android:host="*" />
        </intent-filter>
    </service>

  3. Создайте класс сервиса, который расширяет WearableListenerService и переопределяет onNodeMigrated().

    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 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())
                }
            }
    
            // Callback stops automatically after 20 seconds of data processing.
            // If you think you need more time, delegate to a coroutine or thread.
            runBlocking {
                for (dataItem in dataItemsToHandle) {
                    handleDataItem(nodeId, dataItem)
                }
            }
        }
    }