DataItem
は、システムがハンドヘルドとウェアラブルの間でデータを同期するために使用するインターフェースを定義します。通常、DataItem
は以下のコンポーネントで構成されます。
- ペイロード: データを設定できるバイト配列。独自のオブジェクト シリアル化 / シリアル化解除ができます。ペイロードのサイズは 100 KB に制限されています。
-
パス: スラッシュで始まる一意の文字列(例:
"/path/to/data"
)。
注: Data Layer API でメッセージを送信しデータを同期できる対象は、Android スマートフォンまたは Wear OS スマートウォッチのみです。Wear OS デバイスが iOS デバイスとペア設定されている場合、Data Layer API は機能しません。
このため、ネットワークと通信するための主な手段としては、Data Layer API を使用しないでください。代わりに、若干の違いはあるものの、モバイルアプリと同じパターンを使用してください。
通常、DataItem
を直接実装することはありません。代わりに、次の手順を行います。
-
PutDataRequest
オブジェクトを作成して、アイテムを一意に識別する文字列パスを指定します。 -
setData()
を呼び出して、ペイロードを設定します。 -
同期の遅延がユーザー エクスペリエンスに悪影響をもたらす場合は、
setUrgent()
を呼び出します。 -
DataClient
クラスのputDataItem
メソッドを使用して、データアイテムを作成するようシステムにリクエストします。
データアイテムをリクエストすると、システムは、DataItem
インターフェースを適切に実装するオブジェクトを返します。ただし、setData()
を使用して未加工のバイトを処理するのではなく、データマップを使用することをおすすめします。これにより、Bundle
のようなインターフェースでデータアイテムをエクスポーズできます。
詳細については、DataLayer サンプルアプリをご覧ください。
データをデータマップと同期する
可能な場合は、DataMap
クラスを使用します。このアプローチでは、Android Bundle
形式でデータアイテムを処理できるため、オブジェクトのシリアル化とシリアル化解除はシステムが行い、Key-Value ペアを含むデータの操作はデベロッパーが行うことができます。
データマップを使用する手順は次のとおりです。
-
PutDataMapRequest
オブジェクトを作成して、データアイテムのパスを設定します。注: 接続の両側からデータアイテムにアクセスできるように、パス文字列にはデータアイテムの一意の識別子を指定します。パスはスラッシュで始める必要があります。アプリで階層データを使用している場合は、データの構造に適合するパススキームを作成します。
-
PutDataMapRequest.getDataMap()
を呼び出して、値を設定できるデータマップを取得します。 -
put...()
メソッド(putString()
など)を使用して、データマップに値を設定します。 -
同期の遅延がユーザー エクスペリエンスに悪影響をもたらす場合は、
setUrgent()
を呼び出します。 -
PutDataMapRequest.asPutDataRequest()
を呼び出して、PutDataRequest
オブジェクトを取得します。 -
DataClient
クラスのputDataItem
メソッドを使用して、データアイテムを作成するようシステムにリクエストします。注: ハンドセット デバイスとウェアラブル デバイスの接続が切断された場合、接続が再確立されたときにデータのバッファリングと同期が行われます。
次の例の increaseCounter()
メソッドは、データマップを作成してその中にデータを格納する方法を示しています。
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity() { private lateinit var dataClient: DataClient private var count = 0 ... // Create a data map and put data in it private fun increaseCounter() { val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { dataMap.putInt(COUNT_KEY, count++) asPutDataRequest() } val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq) } ... }
Java
public class MainActivity extends Activity { private static final String COUNT_KEY = "com.example.key.count"; private DataClient dataClient; private int count = 0; ... // Create a data map and put data in it private void increaseCounter() { PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count"); putDataMapReq.getDataMap().putInt(COUNT_KEY, count++); PutDataRequest putDataReq = putDataMapReq.asPutDataRequest(); Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq); } ... }
Tasks
の処理については、リファレンス ドキュメントをご覧ください。
DataItem の優先度を設定する
DataClient
API を使用すると、DataItem
オブジェクトの同期の緊急リクエストを行うことができます。一般に、ユーザー デバイスのバッテリー駆動時間を改善するために、Wear OS ネットワークに対するデータアイテムの配信をシステムが遅延させることがありますが、データアイテムの同期の遅延がユーザー エクスペリエンスに悪影響をもたらす場合は、リクエストを「緊急」としてマークできます。たとえば、操作がすぐに反映されることをユーザーが期待するリモコンアプリの場合、setUrgent()
を呼び出すことで、システムにデータアイテムの同期を直ちに行わせることができます。
setUrgent()
を呼び出さなかった場合、システムは非緊急のデータアイテムの同期を最大で 30 分遅延させることがあります。ただし、遅延が発生したとしても、通常は数分程度で済みます。デフォルトの緊急度は「非緊急」になっているため、以前のバージョンの Wear OS API の即時同期の動作を維持したい場合は、setUrgent()
を使用する必要があります。
データアイテム イベントをリッスンする
データレイヤ接続の一方でデータアイテムが変更された場合は、接続の反対側の変更をユーザーに通知します。そのためには、データアイテム イベントのリスナーを実装します。
次の例のコード スニペットは、以前の例で定義したカウンタの値が変更されたときにアプリに通知します。
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener { private var count = 0 override fun onResume() { super.onResume() Wearable.getDataClient(this).addListener(this) } override fun onPause() { super.onPause() Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> // DataItem changed if (event.type == DataEvent.TYPE_CHANGED) { event.dataItem.also { item -> if (item.uri.path.compareTo("/count") == 0) { DataMapItem.fromDataItem(item).dataMap.apply { updateCount(getInt(COUNT_KEY)) } } } } else if (event.type == DataEvent.TYPE_DELETED) { // DataItem deleted } } } // Method to update the count private fun updateCount(int: Int) { ... } ... }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { private static final String COUNT_KEY = "com.example.key.count"; private int count = 0; @Override protected void onResume() { super.onResume(); Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { super.onPause(); Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED) { // DataItem changed DataItem item = event.getDataItem(); if (item.getUri().getPath().compareTo("/count") == 0) { DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap(); updateCount(dataMap.getInt(COUNT_KEY)); } } else if (event.getType() == DataEvent.TYPE_DELETED) { // DataItem deleted } } } // Method to update the count private void updateCount(int c) { ... } ... }
このアクティビティは、DataClient.OnDataChangedListener
インターフェースを実装しています。また、onResume()
メソッド内でアクティビティ自体をデータアイテム イベントのリスナーとして追加し、onPause()
メソッドでリスナーを削除しています。画像、ビューモデル、サービスを使用した実装を確認するには、DataLayer サンプルアプリをご覧ください。
リスナーをサービスとして実装することもできます。詳細については、データレイヤー イベントをリッスンするをご覧ください。