当用户 设置 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
对象不会被传递,而是会被丢弃。
接收来自旧移动设备的数据
要接收旧移动设备上存档的新的移动设备上的数据,您的移动应用程序必须实现onNodeMigrated()
回调,它是WearableListenerService
类的一部分。要做到这一点,请完成以下步骤
在您的移动应用程序的构建文件中,包含对 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 模块
- 节省电力和电池