使用者設定 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
物件,而會捨棄物件。
接收舊行動裝置的資料
如要在新行動裝置上接收舊行動裝置的封存資料,行動應用程式必須實作 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 模組
- 節省電力和電池