当用户设置 Wear OS 设备时,他们会将 Wear OS 设备连接到特定的移动设备。用户稍后可能决定使用新的移动设备并将其现有的 Wear OS 设备连接到此新移动设备。与 Wear OS 设备相关的一些数据存储在当前连接的移动设备上。
从 Wear OS 4 开始,当用户连接到新的移动设备时,可以将 Wear OS 数据传输到新的移动设备。数据在传输后会自动同步。
用户请求传输时,穿戴式设备数据层会将最初存储在一部移动设备上的 DataItem
对象传递到另一部移动设备。这样可以为您的应用用户提供顺畅的体验。
本文档介绍了如何配置 Wear OS 应用及其配套移动应用来支持这种情形。
准备
数据传输进程处理各个 DataItem
对象的方式有所不同,具体取决于拥有相应数据的应用:
- Wear OS 应用拥有的对象
- 这些对象会保留在 Wear OS 设备上。
- 移动应用拥有的对象
这些对象会在旧设备上归档。然后,系统会将归档的数据打包到
DataItemBuffer
对象中,并将该数据传递到安装在新移动设备上的移动应用。在归档文件提交后,穿戴式设备数据层会立即调用
onNodeMigrated()
监听器,类似于 Wear OS 设备写入数据时应用会如何收到通知。
保留传输的数据
您的应用负责保留传输的 DataItem
对象。在数据传送到新的移动设备后,归档文件很快就会从旧设备上删除。
请确保满足以下每个条件:
- 传输数据所涉及的两个移动设备上都安装了您的应用。
- 两个移动设备上安装的移动应用具有一致的软件包签名。
否则,系统不会传递已归档的 DataItem
对象,而是会将其舍弃。
从旧移动设备接收数据
如需在旧移动设备上归档的新移动设备上接收数据,您的移动应用必须实现 WearableListenerService
类中的 onNodeMigrated()
回调。为此,请完成以下步骤:
在移动应用的 build 文件中,添加对 Google Play 服务中最新版穿戴式设备库的依赖项:
dependencies { ... implementation 'com.google.android.gms:play-services-wearable:18.2.0' }
在应用的清单文件中声明并导出
WearableListenerService
:<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>
创建一个扩展
WearableListenerService
并替换onNodeMigrated()
的服务类。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 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) } } } }
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 Task<DataItem> 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; return 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()); } } for (dataItem in dataItemsToHandle) { handleDataItem(nodeId, dataItem); } // Callback stops automatically after 20 seconds of data processing. // If you think you need more time, delegate to another thread. } }
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 集成 Wear OS 模块
- 节省电量和电量