Android Wear开发 - 数据通讯 - 事件处理

http://developer.android.com/training/wearables/data-layer/events.html#Wait

Section 1 :

Wait for the Status of Data Layer Calls- 等待数据操作结果

You‘ll notice that calls to the data layer API sometimes return a PendingResult, such as putDataItem(). As soon as the PendingResult is created, the operation is queued in the background. If you do nothing else after this, the operation eventually completes silently. However, you‘ll usually want to do something with the result after the operation completes, so the PendingResult lets you wait for the result status, either synchronously or asynchronously.

在进行数据通讯的时候,有时候会返回一个PendingResult对象,例如调用了putDataItem方法.一旦PendingResult对象被构建了,那么数据操作就会在后台队列中.你可以选择是否对这个操作结果进行处理.PendingResult对象可以让你获取到操作结果,无论是同步还是异步.

Asynchronously waiting-异步等待

If your code is running on the main UI thread, do not making blocking calls to the data layer API. You can run the calls asynchronously by adding a callback to the PendingResult object, which fires when the operation is completed:

若你是在UI线程中执行数据操作,那么小心阻塞问题.在这里可以使用回调监听的方式来实现异步等待:

pendingResult.setResultCallback(new ResultCallback<DataItemResult>() {
    @Override
    public void onResult(final DataItemResult result) {
        if(result.getStatus().isSuccess()) {
            Log.d(TAG, "Data item set: " + result.getDataItem().getUri());
        }
    }
});

Synchronously waiting-同步等待

If your code is running on a separate handler thread in a background service (which is the case in a WearableListenerService), it‘s fine for the calls to block. In this case, you can call await() on the PendingResult object, which will block until the request has completed, and return a Result object:

若你在独立的后台服务进程中进行数据操作,那么可以使用同步等待的方式来处理操作结果,在获取到处理结果前都会阻塞住进程.

DataItemResult result = pendingResult.await();
if(result.getStatus().isSuccess()) {
    Log.d(TAG, "Data item set: " + result.getDataItem().getUri());
}

Section 2 :

Listen for Data Layer Events- 监听数据层事件

Because the data layer synchronizes and sends data across the handheld and wearable, you normally want to listen for important events, such as when data items are created, messages are received, or when the wearable and handset are connected.

因为在手机和手表的数据通讯同步的,所以通常需要监听一些重要的事件,如数据创建,消息接收,通讯的连接.

To listen for data layer events, you have two options:

  1. Create a service that extends WearableListenerService.
  2. Create an activity that implements DataApi.DataListener.

With both these options, you override any of the data event callbacks that you care about handling in your implementation.

监听数据通讯,可以通过以下两种方式实现:

  1. 创建一个继承自WearableListenerService的Service
  2. 创建一个实现了DataApi.DataListener数据接口的Activity

1.With a WearableListenerService

You typically create instances of this service in both your wearable and handheld apps. If you don‘t care about data events in one of these apps, then you don‘t need to implement this service in that particular app.
For example, you can have a handheld app that sets and gets data item objects and a wearable app that listens for these updates to update it‘s UI. The wearable never updates any of the data items, so the handheld app doesn‘t listen for any data events from the wearable app.

使用情景

一般而言都会在手机端和手表端都构建一个这样的子类Service. 但如果哪一端对数据事件的监听处理没什么需求,那一端则无需构建.

例如,你可以在手机端构建和传递数据给手表,手表则监听这些数据事件来更新自身界面.但手表端只是单方面的获取数据,不会对数据进行做任何修改,那么,手机端则无需监听数据通讯事件.

You can listen for the following events with WearableListenerService:

  • onDataChanged() - Called when data item objects are created, changed, or deleted. An event on one side of a connection triggers this callback on both sides.
  • onMessageReceived() - A message sent from one side of a connection triggers this callback on the other side of the connection.
  • onPeerConnected() and onPeerDisconnected() - Called when connection with the handheld or wearable is connected or disconnected. Changes in connection state on one side of the connection triggers these callbacks on both sides of the connection.

方法介绍

接下来是介绍WearableListenerService的一些重要事件方法:

  • onDataChanged() :增,删,改,这三种事件都会调用这个接口.并且是两端都会被触发调用.→双向
  • onMessageReceived():消息从一端发送,会调用另一端的接口.→单向
  • onPeerConnected() , onPeerDisconnected():当两端进行连接或者断开的时候会触发.改变一端的连接状态都会调用两端的接口.→双向

To create a WearableListenerService:

  1. Create a class that extends WearableListenerService.
  2. Listen for the events that you care about, such as onDataChanged().
  3. Declare an intent filter in your Android manifest to notify the system about your WearableListenerService. This allows the system to bind your service as needed.

实现步骤

  1. 继承WearableListenerService
  2. 监听数据通讯事件
  3. 在Manifest中声明,并添加intent filter监听com.google.android.gms.wearable.BIND_LISTENER这个动作

代码样例

public class DataLayerListenerService extends WearableListenerService {

    private static final String TAG = "DataLayerSample";
    private static final String START_ACTIVITY_PATH = "/start-activity";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: " + dataEvents);
        }
        final List events = FreezableUtils
                .freezeIterable(dataEvents);

        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .build();

        ConnectionResult connectionResult =
                googleApiClient.blockingConnect(30, TimeUnit.SECONDS);

        if (!connectionResult.isSuccess()) {
            Log.e(TAG, "Failed to connect to GoogleApiClient.");
            return;
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        for (DataEvent event : events) {
            Uri uri = event.getDataItem().getUri();

            // Get the node id from the host value of the URI
            String nodeId = uri.getHost();
            // Set the data of the message to be the bytes of the URI.
            byte[] payload = uri.toString().getBytes();

            // Send the RPC
            Wearable.MessageApi.sendMessage(googleApiClient, nodeId,
                    DATA_ITEM_RECEIVED_PATH, payload);
        }
    }
}

Manifest声明

<service android:name=".DataLayerListenerService">
  <intent-filter>
      <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
  </intent-filter>
</service>

Permissions within Data Layer Callbacks

In order to deliver callbacks to your application for data layer events, Google Play services binds to yourWearableListenerService, and calls your callbacks via IPC. This has the consequence that your callbacks inherit the permissions of the calling process.

If you try to perform a privileged operation within a callback, the security check fails because your callback is running with the identity of the calling process, instead of the identity of your app‘s process.

To fix this, call clearCallingIdentity() , to reset identity after crossing the IPC boundary, and then restore identity with restoreCallingIdentity() when you‘ve completed the privileged operation:

注意点

数据回调接口中的权限问题
为了回调数据事件接口,Google Play会绑定你的Service并且通过IPC的方式调用.这也导致了你的回调接口继承了调用进程的权限.
若想要在回调接口中做某些特权操作,你会发现安全验证失败了,你会发现回调接口中打印出来的进程id,是在触发回调接口的进程的id,而不是你的应用的进程.
为了解决这个问题,先调用clearCallingIdentity()来重置id,恢复为应用进程id;再执行你所需要的操作;最后再调用恢复为restoreCallingIdentity()调用者的id.

long token = Binder.clearCallingIdentity();
try {
    performOperationRequiringPermissions();
} finally {
    Binder.restoreCallingIdentity(token);
}

2.With a Listener Activity

If your app only cares about data layer events when the user is interacting with the app and does not need a long-running service to handle every data change, you can listen for events in an activity by implementing one or more of the following interfaces:

  • DataApi.DataListener
  • MessageApi.MessageListener
  • NodeApi.NodeListener

方法介绍

若你的应用只是需要在用户打开时监听数据通讯事件,而不需要在后台监听数据改变,那么可以实现以下接口来实现你的需求.

  • DataApi.DataListener
  • MessageApi.MessageListener
  • NodeApi.NodeListener

To create an activity that listens for data events:

  1. Implement the desired interfaces.
  2. In onCreate(Bundle), create an instance of GoogleApiClient to work with the data layer API.
  3. In onStart(), call connect() to connect the client to Google Play services.
  4. When the connection to Google Play services is established, the system calls onConnected(). This is where you call DataApi.addListener(), MessageApi.addListener(), or NodeApi.addListener() to notify Google Play services that your activity is interested in listening for data layer events.
  5. In onStop(), unregister any listeners with DataApi.removeListener(), MessageApi.removeListener(), or NodeApi.removeListener().
  6. Implement onDataChanged(), onMessageReceived(), onPeerConnected(), and onPeerDisconnected(), depending on the interfaces that you implemented.

实现步骤

接下来是创建一个监听数据通讯事件的Activity

  1. 实现接口 : 实现上面列举的接口(根据需求来定,不需要全部都实现)
  2. 创建服务对象 : 在onCreate方法中创建一个GoogleApiClient对象来实现与数据通讯的连接.
  3. 连接服务 : 在onStart方法中调用GoogleApiClient的connect方法来连接服务
  4. 注册监听器 : 当GoogleApiClient连接上了服务,会回调onConnected方法,那么我们就可以在这里中注册监听器,来监听我们所关心的通讯事件.
  5. 反注册监听器,并断开服务 : 在onStop方法中,反注册之前注册的监听器,然后再断开GoogleApiClient服务连接.
  6. 实现事件回调接口 : 根据注册的监听器实现接口,处理相关的需求.

代码样例

以下是一个实现了DataApi.DataListener的样例:

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

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

    @Override
    protected void onStart() {
        super.onStart();
        if (!mResolvingError) {
            mGoogleApiClient.connect();
        }
    }

   @Override
    public void onConnected(Bundle connectionHint) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Connected to Google Api Service");
        }
        Wearable.DataApi.addListener(mGoogleApiClient, this);
    }

    @Override
    protected void onStop() {
        if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
            Wearable.DataApi.removeListener(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
        super.onStop();
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
            } else if (event.getType() == DataEvent.TYPE_CHANGED) {
                 Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
            }
        }
    }
时间: 2024-10-09 13:05:57

Android Wear开发 - 数据通讯 - 事件处理的相关文章

Android Wear开发 - 数据通讯 - 第三节 : 事件处理

http://developer.android.com/training/wearables/data-layer/events.html 以下是本人在学习官方开发文档时的笔记,主要是翻译为主,并在中间会插入一些自己的总结与研究,希望对读者有所帮助. 本文分为2大部分:Section1 : 如何获取数据通讯的结果.Section2 : 如何监听数据层中的数据事件.其中Section2分为2模块: 1. 继承WearableListenerService; 2. Activity实现数据接口.

Android Wear开发 - 数据通讯 - 第二节 : 数据的发送与接收

本节由介绍3种数据的发送接收:1.Data Items : 比特类型数据,限制100KB以内2.Assets : 资源类型数据,大小无上限3.Message : 发送消息,触发指令 http://developer.android.com/training/wearables/data-layer/data-items.html 1.Syncing Data Items DataItem定义了同步手机和手表的数据接口.一个DataItem对象一般包括下面2个部分: 负载 : 一个比特类型数组,支

Android Wear开发 - 数据通讯 - 第一节 : 连接数据层

http://developer.android.com/training/wearables/data-layer/accessing.html Accessing the Wearable Data Layer-数据层连接 GoogleApiClient是一个用于整合所有谷歌服务的入口,想要连接数据层,需要构建一个对象.GoogleApiClient提供了一个builder方法简化了构建对象的步骤. GoogleApiClient mGoogleApiClient = new GoogleA

Android Wear开发 - 数据通讯 - 第四节 : 数据封装(解决不能序列化问题)

一. 前言 背景 一开始笔者在研究数据发送与接收的时候,看到Wear数据类DataMap除了可以put基本类型外,还有个fromBundle方法来构建一个DataMap对象.所以一口气的将原本功能上的序列化对象传递过去,结果手表端一直都收不到消息. 问题原因 后来查阅了开发者文档,发现这个Bundle并没有我们在Intent中传递数据的那么强大,它并不支持序列化!先附上开发者文档的说明: Returns a DataMap from a Bundle. The input Bundle is e

IDEA搭建Android wear开发环境,Android wear,I&#39;m comming!

随着google发布了android wear这个东西,然后又有了三星的gear,LG的G watch以及moto 360,苹果由发布了apple watch,未来可能在智能手表行业又有一场战争.当然这只是笔者的个人观点,仅供参考. 作为开发者,当然关心的是只能手表的开发了,所以我们来搭建一下android wear的开发环境吧! 搭建android wear开发环境,我们需要以下的软件Intellij 13.1.3,android-sdk 23.0.02. 首先需要下载安装好android-s

Android Wear 开发入门

大家好,我是陆嘉杰,我是一名Android开发者.我想和大家进行一些技术交流,希望越来越多的人能和我成为好朋友. 大家都知道,智能手表是下一个开发的风口,而这方面的技术又属于前沿,所以和大家分享下Android Wear的开发流程. 首先,我推荐大家使用Android Studio来进行Wear的开发,这也是谷歌推荐的,本次讲授过程也将以Android Studio作为开发集成环境进行. 下面我们来创建Android Wear项目. 请注意,Android Wear项目中同时包含mobile和w

Android Wear 开发入门——如何创建一个手机与可穿戴设备关联的通知(Notification)

创建通知 为了创建在手机与可穿戴设备中都能展现的通知,可以使用 NotificationCompat.Builder.通过该类创建的通知,系统会处理该通知是否展现在手机或者穿戴设备中. 导入必要的类库 在开发之前首先需要导入以下类库 importandroid.support.v4.app.NotificationCompat; importandroid.support.v4.app.NotificationManagerCompat; importandroid.support.v4.app

想做Android Wear开发?你得先搞明白这四件事

手环和手表的腕上穿戴之争,随着Apple Watch发布和Android Wear不断完善而告一段落.尽管续航上略有缺陷,但手表以其类似手机可扩展的生态环境赢得了众多巨头的支持. Google曾透露,Android Wear发布三周左右应用数就超过了Google Glass,并将有数以千计的app不断加入.Apple Watch发布的该月内,雷锋网驻硅谷的记者发现已有公司开始招聘相关开发者. 国外的开发者生态一向积极,国内虽明面上动静不大,但实际各家也已经都在暗自开动.鉴于Apple Watch

在Android Wear开发中使用蓝牙调试同时操作手机与手表设备

在开发Android Wear应用过程中需要对手表和手机进行同时操作,可以通过蓝牙同时对手机和手表进行操作. 1 打开手表和手机的调试设置 打开手机的usb调试 打开手表设置的开发者选项,选中Debug over Bluetooth   如果是首次使用手表调试,需要在Setting中找到About,单击7次打开开发者选项 2 连接手表到开发工具 在手机端打开Android Wear App,进入Setting,选中Debugging over Bluetooth,会发现当前状态是 <span s