Перенос данных Wear OS на новое мобильное устройство

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

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

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

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

Подготовка

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

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

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

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

Сохранение переданных данных

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

Убедитесь, что каждое из следующих условий выполняется:

  1. Ваше приложение установлено на обоих мобильных устройствах, участвующих в передаче данных.
  2. Мобильные приложения, установленные на каждом мобильном устройстве, имеют совпадающие цифровые подписи пакетов.

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

Получение данных со старого мобильного устройства

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

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

    dependencies {
        ...
        implementation 'com.google.android.gms:play-services-wearable:19.0.0'
    }
  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)
                }
            }
        }
    }

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}