用户在设置 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
对象。数据交付到新移动设备后不久,旧设备上的存档就会被删除。
确保以下每个条件都为真
- 您的应用已安装在参与传输的两台移动设备上。
- 安装在每台移动设备上的移动应用具有匹配的软件包签名。
否则,存档的 DataItem
对象将不会交付,而是被丢弃。
从旧移动设备接收数据
为了在新移动设备上接收在旧移动设备上存档的数据,您的移动应用必须实现 WearableListenerService
类中的 onNodeMigrated()
回调。为此,请完成以下步骤
在您的移动应用的构建文件中,添加对 Google Play services 中最新版可穿戴设备库的依赖项
dependencies { ... implementation 'com.google.android.gms:play-services-wearable:19.0.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 模块
- 节约电量和电池续航