Skip to content

Most visited

Recently visited

navigation

处理数据层 Event

当您调用 Data Layer API 时,可以在调用完成时获得其状态。您还可以侦听因您的应用在 Android Wear 网络上任意位置做出的数据更改而引发的数据 Event。

:Wear 应用可以使用 Data Layer API 与手机应用通信,但不建议使用此 API 连接网络

等待数据层调用的状态

调用 Data Layer API 有时会返回 PendingResult,例如 putDataItem()PendingResult 创建后,操作在后台排队。如果您在此之后未执行其他操作,操作最终会以静默方式完成。不过,您通常想在操作完成后对结果进行某种处理,因此 PendingResult 允许您以同步或异步方式等待结果状态。

异步调用

如果您的代码在主界面线程上运行,请勿对 Data Layer API 进行阻塞调用。您可以通过为 PendingResult 对象添加回调函数,以异步方式运行调用,该函数在操作完成时触发:

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

同步调用

如果您的代码在某个后台 Service 中(在 WearableListenerService 中便是如此)的一个独立处理线程中运行,则可以阻塞调用。在此情况下,您可以调用 PendingResult 对象上的 await(),它会阻塞直至请求完成,并返回 Result 对象:

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

侦听数据层 Event

由于数据层跨手持式设备和穿戴式设备同步和发送数据,因此通常有必要侦听重要 Event。举例来说,此类 Event 包括创建数据项和接收消息。

要侦听数据层 Event,您有两个选择:

无论做哪一个选择,您都需要重写待处理 Event 的数据 Event 回调函数。

使用 WearableListenerService

您通常同时在穿戴式设备和手持式设备应用中创建此 Service 的实例。如果您对其中一个应用中的数据 Event 不感兴趣,则无需在该特定应用中实现此 Service。

例如,您可以让手持式设备应用设置和获取数据项对象,以及让穿戴式设备应用侦听这些更新以更新其界面。穿戴式设备应用从不更新任何数据项,因此手持式设备应用不会侦听任何来自穿戴式设备应用的数据 Event。

您可以使用 WearableListenerService 侦听的部分 Event 如下:

以上所有 Event 都在后台线程而不是主线程中执行。

要创建 WearableListenerService,请执行以下步骤:

  1. 创建一个扩展 WearableListenerService 的类。
  2. 侦听您感兴趣的 Event,例如 onDataChanged()
  3. 在您的 Android 清单中声明一个 Intent 过滤器,以向系统通知您的 WearableListenerService 的相关信息。此声明允许系统根据需要绑定您的 Service。

以下示例显示如何实现一个简单的 WearableListenerService

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);
        }

        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 : dataEvents) {
            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);
        }
    }
}

下一部分说明如何将 Intent 过滤器与此侦听器结合使用。

将过滤器与 WearableListenerService 结合使用

上文所示 WearableListenerService 示例的 Intent 过滤器可能类似于如下:

<service android:name=".DataLayerListenerService">
  <intent-filter>
      <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
      <data android:scheme="wear" android:host="*"
               android:path="/start-activity" />
  </intent-filter>
</service>

在此过滤器中,DATA_CHANGED 操作取代了之前推荐的 BIND_LISTENER 操作,使得只有特定 Event 才能唤醒或启动您的应用。这一变化提高了系统效率,并降低了电池消耗以及其他与应用有关的系统开销。在本例中,手表侦听 /start-activity 数据项,手机则侦听 /data-item-received 消息回复。

标准 Android 过滤器匹配规则适用。您可以为每个 manifest 指定多个 Service,为每个 Service 指定多个 Intent 过滤器,为每个过滤器指定多项操作,以及为每个过滤器指定多个数据节。过滤器可在通配符主机或指定主机上进行匹配。要在通配符主机上进行匹配,请使用 host="*"。要在指定主机上进行匹配,请指定 host=<node_id>

您还可以匹配文字路径或路径前缀。如果您要按路径或路径前缀匹配,您必须指定通配符或指定主机。否则,系统将忽略您指定的路径。

如需了解有关 Wear 支持的过滤器类型的详细信息,请参阅 WearableListenerService 的 API 参考文档。

如需了解有关数据过滤器和匹配规则的详细信息,请参阅 data 清单元素的 API 参考文档。

匹配 Intent 过滤器时,需要牢记两条重要规则:

使用实时侦听器

如果您的应用只关心用户与应用交互时的数据层 Event,不一定需要长时间运行的 Service 来处理每个数据变化。在此类情况下,您可以通过实现下列一个或多个接口,侦听 Activity 中的 Event:

要创建侦听数据 Event 的 Activity,请执行下列操作:

  1. 实现所需接口。
  2. onCreate() 中,创建与 Data Layer API 配合使用的 GoogleApiClient 实例。
  3. onStart() 中,调用 connect(),以将客户端与 Google Play 服务相连。
  4. 与 Google Play 服务建立连接后,系统会调用 onConnected()。可在此处调用 DataApi.addListener()MessageApi.addListener()CapabilityApi.addListener(),以通知 Google Play 服务,您的 Activity 有意侦听数据层 Event。
  5. onStop() 中,使用 DataApi.removeListener()MessageApi.removeListener()CapabilityApi.removeListener() 取消注册所有侦听器。
  6. onConnected() 中添加侦听器和在 onStop() 中移除它们的替代措施是,在 Activity 的 onResume() 中添加过滤的侦听器,并在 onPause() 中将它移除,以只接收与当前应用状态有关的数据。

  7. 实现 onDataChanged() onMessageReceived()onCapabilityChanged() 函数,或来自 Channel API 侦听器函数中的函数,具体取决于您实现的接口。这些函数在主线程上调用。(不过,在 8.1 以下版本的 Google Play 服务客户端内容库中,不会在主线程上调用侦听器函数。)

下面是一个实现 DataApi.DataListener 的示例:

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

    private GoogleApiClient mGoogleApiClient;

    @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());
            }
        }
    }
}

将过滤器与实时侦听器结合使用

正如您可以为基于清单的 WearableListenerService 对象指定 Intent 过滤器,您还可以在通过 Wearable API 注册侦听器时使用 Intent 过滤器。同样的规则对基于 API 的侦听器和基于 manifest 的侦听器均适用。

一种常见模式是,在 Activity 的 onResume() 函数中注册具有指定路径或路径前缀的侦听器,以及在 Activity 的 onPause() 函数中移除该侦听器。以这种方式实现侦听器可以让您的应用更有选择地接收 Event,从而改善其设计和效率。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)