classMyWearableListenerService:WearableListenerService(){valdataClient:DataClient=Wearable.getDataClient(this)privatefunshouldHandleDataItem(nodeId:String,dataItem:DataItem):Boolean{// Your logic herereturndataItem.uri.path?.startsWith("/my_feature_path/")==true}privatefunhandleDataItem(nodeId:String,dataItem:DataItem){valdata=dataItem.data?:returnvalpath=dataItem.uri.path?:return// Your logic hereif(data.toString().startsWith("Please restore")){dataClient.putDataItem(PutDataRequest.create(path).setData(data))}}overridefunonNodeMigrated(nodeId:String,archive:DataItemBuffer){valdataItemsToHandle=mutableListOf<DataItem>()for(dataIteminarchive){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(dataItemindataItemsToHandle){handleDataItem(nodeId,dataItem)}}}}
Java
publicclassMyWearableListenerServiceextendsWearableListenerService{privatefinalDataClientdataClient=Wearable.getDataClient(this);privatebooleanshouldHandleDataItem(StringnodeId,DataItemdataItem){// Your logic herereturnObjects.requireNonNull(dataItem.getUri().getPath()).startsWith("/my_feature_path/");}privateTask<DataItem>handleDataItem(StringnodeId,DataItemdataItem){byte[]data=dataItem.getData();Stringpath=dataItem.getUri().getPath();// Your logic hereif(data!=null && path!=null && Arrays.toString(data).startsWith("Please restore")){assertpath!=null;returndataClient.putDataItem(PutDataRequest.create(path).setData(data));}@OverridepublicvoidonNodeMigrated(@NonNullStringnodeId,DataItemBufferarchive){List<DataItem>dataItemsToHandle=newArrayList<>();for(DataItemdataItem:archive){if(shouldHandleDataItem(nodeId,dataItem)){dataItemsToHandle.add(dataItem.freeze());}}for(dataItemindataItemsToHandle){handleDataItem(nodeId,dataItem);}// Callback stops automatically after 20 seconds of data processing.// If you think you need more time, delegate to another thread.}}
[null,null,["最后更新时间 (UTC):2025-08-17。"],[],[],null,["# Transfer Wear OS data to a new mobile device\n\nWhen users [set up a Wear OS device](https://support.google.com/wearos/answer/6056630), they connect the Wear OS device to a\nparticular mobile device. The user might later decide to get a new mobile device\nand connect their existing Wear OS device to this new mobile device. Some data\nrelated to a Wear OS device is stored on the currently-connected mobile device.\n\nStarting in Wear OS 4, when users connect to a new mobile device, they can\ntransfer Wear OS data to the new mobile device. Data is synced automatically\nwhen it's transferred.\n| **Note:** This process of transferring data to a new mobile device is different from [cloud backup and restore](/training/wearables/data/cloud-backup-restore), where the user restores data to a new Wear OS device.\n\nWhen the user requests a transfer, the [Wearable Data Layer](/training/wearables/data/data-layer) delivers\n[`DataItem`](https://developers.google.com/android/reference/com/google/android/gms/wearable/DataItem) objects, originally stored on one mobile device, to the other\nmobile device. This allows a seamless experience for users of your app.\n\nThis document describes how you can configure your Wear OS app, and its\ncompanion mobile app, to support this scenario.\n\nPreparation\n-----------\n\nThe data transfer process handles `DataItem` objects differently, depending on\nwhich app owns the data:\n\nObjects owned by the Wear OS app\n: These objects are preserved on the Wear OS device.\n\nObjects owned by the mobile app\n\n: These objects are archived on the old device. The system then packages the\n archived data into a [`DataItemBuffer`](https://developers.google.com/android/reference/com/google/android/gms/wearable/DataItemBuffer) object and delivers this data to the\n mobile app that's installed on the new mobile device.\n\n Immediately after the archive is delivered, the Wearable Data Layer invokes\n the [`onNodeMigrated()`](https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService#onNodeMigrated(java.lang.String,%20com.google.android.gms.wearable.DataItemBuffer)) listener, similarly to how your app is notified\n when data is written by the Wear OS device.\n | **Note:** Data is transferred only if it's stored in the Wearable Data Layer.\n\nPreserve transferred data\n-------------------------\n\n| **Warning:** To avoid losing data, follow the guidance in this section.\n\nIt's your app's responsibility to preserve the transferred `DataItem` objects.\nShortly after the data is delivered to the new mobile device, the archive is\ndeleted off of the old device.\n\nMake sure each of the following conditions is true:\n\n1. Your app is installed on both mobile devices that are involved in the transfer.\n2. The mobile apps, installed on each mobile device, have package signatures that match.\n\nOtherwise, the archived `DataItem` objects aren't delivered and are instead\ndiscarded.\n\nReceive data from the old mobile device\n---------------------------------------\n\nTo receive data on the new mobile device that was archived on the old mobile\ndevice, your mobile app must implement the [`onNodeMigrated()`](https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService#onNodeMigrated(java.lang.String,%20com.google.android.gms.wearable.DataItemBuffer)) callback,\npart of the `WearableListenerService` class. To do so, complete the following\nsteps:\n\n1. In your mobile app's build file, include a dependency on the latest version\n of the wearable library in Google Play services:\n\n ```groovy\n dependencies {\n ...\n implementation 'com.google.android.gms:play-services-wearable:19.0.0'\n }\n ```\n2. Declare and export the `WearableListenerService` in your app's\n manifest file:\n\n \u003cservice\n android:name=\".MyWearableListenerService\"\n android:exported=\"true\"\u003e\n \u003cintent-filter\u003e\n ...\n \u003caction android:name=\"com.google.android.gms.wearable.NODE_MIGRATED\" /\u003e\n \u003cdata android:scheme=\"wear\" /\u003e\n \u003c/intent-filter\u003e\n \u003c/service\u003e\n\n3. Create a service class which extends `WearableListenerService` and overrides\n `onNodeMigrated()`.\n\n **Caution:** To preserve system resources such as battery life, and to prevent ANRs, don't execute any power-demanding or time-consuming tasks in the `onNodeMigrated()` handler. \n\n ### Kotlin\n\n ```kotlin\n class MyWearableListenerService : WearableListenerService() {\n val dataClient: DataClient = Wearable.getDataClient(this)\n\n private fun shouldHandleDataItem(nodeId: String,\n dataItem: DataItem): Boolean {\n // Your logic here\n return dataItem.uri.path?.startsWith(\"/my_feature_path/\") == true\n }\n\n private fun handleDataItem(nodeId: String, dataItem: DataItem) {\n val data = dataItem.data ?: return\n val path = dataItem.uri.path ?: return\n // Your logic here\n if (data.toString().startsWith(\"Please restore\")) {\n dataClient.putDataItem(\n PutDataRequest.create(path).setData(data)\n )\n }\n }\n\n override fun onNodeMigrated(nodeId: String, archive: DataItemBuffer) {\n val dataItemsToHandle = mutableListOf\u003cDataItem\u003e()\n\n for (dataItem in archive) {\n if (shouldHandleDataItem(nodeId, dataItem)) {\n dataItemsToHandle.add(dataItem.freeze())\n }\n }\n\n // Callback stops automatically after 20 seconds of data processing.\n // If you think you need more time, delegate to a coroutine or thread.\n runBlocking {\n for (dataItem in dataItemsToHandle) {\n handleDataItem(nodeId, dataItem)\n }\n }\n }\n }\n ```\n\n ### Java\n\n ```java\n public class MyWearableListenerService extends WearableListenerService {\n private final DataClient dataClient = Wearable.getDataClient(this);\n\n private boolean shouldHandleDataItem(String nodeId, DataItem dataItem) {\n // Your logic here\n return Objects.requireNonNull(dataItem.getUri().getPath())\n .startsWith(\"/my_feature_path/\");\n }\n\n private Task\u003cDataItem\u003e handleDataItem(String nodeId, DataItem dataItem) {\n byte[] data = dataItem.getData();\n String path = dataItem.getUri().getPath();\n // Your logic here\n if (data != null && path != null && Arrays.toString(data)\n .startsWith(\"Please restore\")) {\n assert path != null;\n return dataClient.putDataItem(\n PutDataRequest.create(path).setData(data));\n }\n\n @Override\n public void onNodeMigrated(@NonNull String nodeId, DataItemBuffer archive) {\n List\u003cDataItem\u003e dataItemsToHandle = new ArrayList\u003c\u003e();\n\n for (DataItem dataItem : archive) {\n if (shouldHandleDataItem(nodeId, dataItem)) {\n dataItemsToHandle.add(dataItem.freeze());\n }\n }\n\n for (dataItem in dataItemsToHandle) {\n handleDataItem(nodeId, dataItem);\n }\n\n // Callback stops automatically after 20 seconds of data processing.\n // If you think you need more time, delegate to another thread.\n }\n }\n ```\n\nRecommended for you\n-------------------\n\n- Note: link text is displayed when JavaScript is off\n- [Integrate a Wear OS module](/health-and-fitness/guides/basic-fitness-app/integrate-wear-os)\n- [Conserve power and battery](/training/wearables/apps/power)"]]