Android, 時々Web

Androidアプリを作ったり、Webサービスを作ったりする中で困ったことや詰まったことを解決したときの備忘録です。備忘録なので、正しい答えが書いてあるとは限りません。

【翻訳】Android Wearでスマホとウェアラブルの間でデータを同期する

Android Wear向けのアプリを開発していて躓くのが、Wear側とHandheld側でデータをどのように同期するかということ。

それを解決してくれるDataApiというAPIが用意されているが、日本語の情報が少なくどのようにして使うべきなのかがわかりにくい。

ということで、Android DevelopersのSyncing Data Itemsという記事を理解するために翻訳してみたので、それを共有してみます。

英語はあまり得意ではないので、誤訳などがあったらツッコんで下さい。。

 

#ここから引用、翻訳

Syncing Data Items
データアイテムの同期

A DataItem defines the data interface that the system uses to synchronize data between handhelds and wearables. A DataItem generally consists of the following items:

DataItemはシステムが手持ち端末とウェラブル端末との間でデータを同期するのに使用する、データインタフェースを定義します。DataItemは一般的に以下の項目から成ります:

  • Payload - A byte array, which you can set with whatever data you wish, allowing you to do your own object serialization and deserialization. The size of the payload is limited to 100KB.
    ペイロード‐バイト配列。あなたが希望するシリアライズとデシリアライズをすることができるどのようなデータでもセットすることができます。ペイロードの最大サイズは100KBです。
  • Path - A unique string that must start with a forward slash (for instance, "/path/to/data")
    パス‐スラッシュで始まるユニークな文字列(たとえば、"/path/to/data")

You normally don't implement DataItem directly. Instead, you:
普通、直接DataItemを実装しません。その代わりに:

  1. Create a PutDataRequest object, specifying a string path to uniquely identify the item.
    アイテムを一意に特定できるパス文字列を指定し、PutDataRequestオブジェクトを作成します。
  2. Call setData() to set the payload.
    ペイロードをセットするためにsetData()を呼びます。
  3. Call DataApi.putDataItem() to request the system to create the data item.
    データアイテムの作成をシステムにリクエストするためにDataApi.putDataItem()を呼びます。
  4. When requesting data items, the system returns objects that properly implement the DataItem interface.
    データアイテムをリクエストした時、システムはDataItemインタフェースを適切に実装したオブジェクトを返します。

However, instead of working with raw bytes using setData(), we recommend you use a data map, which exposes a data item in an easy-to-use Bundle-like interface.
しかし、setData()を使用して生のバイト配列を利用して動作させる代わりに、データマップを使用することを推奨します。

Sync Data with a Data Map
データマップを用いたデータの同期


When possible, use the DataMap class. This approach lets you work with data items in the form of an AndroidBundle, so object serialization and de-serialization is done for you, and you can manipulate data with key-value pairs.
可能であれば、DataMapクラスを使用してください。このアプローチはデータアイテムをAndroidのBundleの形で利用できます。すなわち、オブジェクトのシリアライズとデシリアライズが行われ、データをキー・バリューの対で操作することができます。

To use a data map:
データマップを使用するために:

  1. Create a PutDataMapRequest object, setting the path of the data item.
    PutDataMapRequestオブジェクトを作成し、データアイテムのパスをセットします。

    Note: The path string is a unique identifier for the data item that allows you to access it from either side of the connection. The path must begin with a forward slash. If you're using hierarchical data in your app, you should create a path scheme that matches the structure of the data.
    注意:パス文字列は、接続のどちら側からでもアクセスできるようにする、データアイテムの一意な識別子です。パスはスラッシュで始まる必要があります。あなたが階層的なデータをアプリで使用している場合、パスのスキーマをデータの構造にマッチするように作るべきです。

  2. Call PutDataMapRequest.getDataMap() to obtain a data map that you can set values on.
    値をセットできるデータマップを取得するために、PutDataMapRequest.getDataMap()を呼びます。
  3. Set any desired values for the data map using the put...() methods, such as putString().
    putString()のようなput…()メソッドを使用して、データマップに値をセットします。
  4. Call PutDataMapRequest.asPutDataRequest() to obtain a PutDataRequest object.
    PutDataRequestオブジェクトを取得するために、PutDataMapRequest.asPutDataRequest()を呼びます。
  5. Call DataApi.putDataItem() to request the system to create the data item.
    システムにデータアイテムの作成をリクエストするために、DataApi.putDataItem()を呼びます。

    Note: If the handset and wearable devices are disconnected, the data is buffered and synced when the connection is re-established.
    注意:もしスマートフォンウェアラブル端末が切断されていれば、データはバッファされ接続が再確立された時に同期されます。

The increaseCounter() method in the following example shows how to create a data map and put data in it:
以下の例のincreaseCounter()メソッドはどのようにしてデータマップを作成し、それにデータを格納するかを示します。

public class MainActivity extends Activity implements
       
DataApi.DataListener,
       
GoogleApiClient.ConnectionCallbacks,
       
GoogleApiClient.OnConnectionFailedListener {

   
private static final String COUNT_KEY = "com.example.key.count";

   
private GoogleApiClient mGoogleApiClient;
   
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();
       
PendingResult<DataApi.DataItemResult> pendingResult =
               
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
   
}

   
...
}

For more information about handling the PendingResult object, see Wait for the Status of Data Layer Calls.
PendingResultオブジェクトのハンドリングについてのさらなる情報は、Wait for the Status of Layer Callsを参照してください。

Listen for Data Item Events
データアイテムイベントを受け取る


If one side of the data layer connection changes a data item, you probably want to be notified of any changes on the other side of the connection. You can do this by implementing a listener for data item events.
データレイヤー接続の片側がデータアイテムを変更すると、あなたはおそらく接続のもう片側で変更の通知を望むでしょう。あなたはデータアイテムイベントのリスナを実装することで、これを実現できます。

The code snippet in the following example notifies your app when the value of the counter defined in the previous example changes:
以下の例のコードスニペットは、前の例で定義されたカウンタの値が変更される時、あなたのアプリに通知します:

public class MainActivity extends Activity implements
       
DataApi.DataListener,
       
GoogleApiClient.ConnectionCallbacks,
       
GoogleApiClient.OnConnectionFailedListener {

   
private static final String COUNT_KEY = "com.example.key.count";

   
private GoogleApiClient mGoogleApiClient;
   
private int count = 0;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView
(R.layout.activity_main);

        mGoogleApiClient
= new GoogleApiClient.Builder(this)
               
.addApi(Wearable.API)
               
.addConnectionCallbacks(this)
               
.addOnConnectionFailedListener(this)
               
.build();
   
}

   
@Override
   
protected void onResume() {
       
super.onResume();
        mGoogleApiClient
.connect();
   
}

   
@Override
   
public void onConnected(Bundle bundle) {
       
Wearable.DataApi.addListener(mGoogleApiClient, this);
   
}

   
@Override
   
protected void onPause() {
       
super.onPause();
       
Wearable.DataApi.removeListener(mGoogleApiClient, this);
        mGoogleApiClient
.disconnect();
   
}

   
@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
           
}
       
}
   
}

   
// Our method to update the count
   
private void updateCount(int c) { ... }

   
...
}

This activity implements the DataItem.DataListener interface. This activity adds itself as a listener for data item events inside the onConnected() method and removes the listener in the onPause() method.
このアクティビティはDataItem.DataListerインタフェースを実装しています。このアクティビティはデータアイテムイベントのためにonConnected()メソッドの中で自身をリスナとして追加し、onPuase()メソッドの中でリスナを削除しています。

You can also implement the listener as a service. For more information, see Listen for Data Layer Events.
あなたはリスナをサービスとして実装することもできます。さらなる情報はListen for Data Layer Eventsを参照してください。

#ここまで引用、翻訳

 

引用元の記事の著作権Googleに帰属しており、Creative Commons — Attribution 2.5 Generic — CC BY 2.5によってライセンスされています。そのためこの翻訳文も同ライセンスでライセンスされます。また、翻訳文を追加しています。