Android wear的数据通讯方式之DataItems

Android wear 提供了多种手机和手表之间的数据通讯方式。

DataItem就是一个手机和手表都可以获取的共享数据空间,基于GoogleApiClient(并不意味着必须才能使用,只要手机有google的api即可),适用于小于100kb的数据共享。

既然是一个共享内存(队列),那么手机和手表既可以是发送方,也可以是接收方,但是每方都需要先创建一个GoogleApiClient 实例:

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(new ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle connectionHint) {
                    Log.d(TAG, "onConnected: " + connectionHint);
                    // Now you can use the Data Layer API
                }
                @Override
                public void onConnectionSuspended(int cause) {
                    Log.d(TAG, "onConnectionSuspended: " + cause);
                }
        })
        .addOnConnectionFailedListener(new OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult result) {
                    Log.d(TAG, "onConnectionFailed: " + result);
                }
            })
        // Request access only to the Wearable API
        .addApi(Wearable.API)
        .build();

发送数据的代码如下:

PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
PendingResult pendingResult =Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);

第一行的/count表示的是路径,必须以/开头,可以理解为不同的数据域

getDataMap()获取的是一个共享的map,共享的数据就存放在这里


对于接收方接收数据,可以直接读取,也可以通过监听器,

直接读取:

    PendingResult results = Wearable.DataApi.getDataItems(mGoogleApiClient);
    results.setResultCallback(new ResultCallback() {
        @Override
        public void onResult(DataItemBuffer dataItems) {
        if (dataItems.getCount() != 0) {
            for (int i = 0; i < dataItems.getCount(); i++) {
                DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItems.get(i));
                if (dataMapItem.getDataMap().containsKey(COLOR_KEY)) {
                    mSelectedColor = dataMapItem.getDataMap().getInt(COLOR_KEY);
                    }
                }
            }
            dataItems.release();
        }
    });

这个方法并没有把数据分成不同路径,解决方法见 http://stackoverflow.com/questions/24601251/what-is-the-uri-for-wearable-dataapi-getdataitem-after-using-putdatamaprequest


监听器读取:

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.onStart();
        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) { ... }

    ...
}
以上抄自官方文档。这里给出了一个具体的activity的例子,提示了GoogleApiClient的连接打开和关闭的方式。

至此,我们就可以通过dataitem来传递数据了。


需要注意的:

  • 只有在同一个应用内(即手机和手表应用的applicationID相同)才能传递数据。
  • 发送数据的时候要注意,mGoogleApiClient.connect();要提前调用,不能出现如下代码:
mGoogleApiClient.connect();
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
PendingResult pendingResult =Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
mGoogleApiClient.disconnect();
因为调用.connect()需要一段时间才能连接上,而后面的代码不会成功执行。正确的写法应该把传输数据的代码放在public void onConnected(Bundle bundle){}里面。


参考资料:

http://developer.android.com/training/wearables/data-layer/data-items.html

http://stackoverflow.com/questions/24595679/how-to-use-dataitem-of-android-wear


你可能感兴趣的:(android)