以下内容翻译自android wear的官方教程,本人水平有限,如有错误欢迎指出
home
以下正文
但你在调用数据层API的时候,你可以收到当它完成时的状态。你也可以监听数据层事件,这个数据改变事件可以在Android Wear网络中任意节点发生。
等待数据层调用状态
你可能发现调用数据层AP有时会返回一个 PendingResult
,比如在调用putDataItem()的时候。在PendingResult创建的时候,操作在后台被排序到任务队列当中。如果你在之后不操作它,这个操作最终会安静的完成。但是,你经常会想在操作完成后做些什么,所以PendingResult会让你以同步或异步的方式获得结果状态。
异步调用
如果你的代码在主UI线程运行,不要调用会阻塞的数据层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());
}
}
});
同步调用
如果你的代码运行在一个后台的handler线程( 在WearableListenerService
实例中),这里可以用阻塞的方法。你可以调用await()在PendingResult对象,这个方法将会阻塞到请求完成并返回Result对象.
DataItemResult result = pendingResult.await();
if(result.getStatus().isSuccess()) {
Log.d(TAG, "Data item set: " + result.getDataItem().getUri());
}
监听数据层事件
因为数据层在手表和手机之间同步和发送数据。它通常有必要监听重要的事件。比如说创建data items或接受一个messages。
实现监听数据层,你有两种选择:
- 创建继承了 WearableListenerService
的服务 - 创建实现了 DataApi.DataListener
的activity。
对于这两种选择,你可以重写感兴趣数据事件的回调函数来处理相关事件。
用继承WearableListenerService方法
通常你可以在你的手表和手机的app上创建这个service的实例。如果其中一个app对数据事件不感兴趣,你可以不实现这个service。
比如,你可以有一个手机app来创建和获取data items而手表app监听这些更新并更新UI。由于手表app不产生data items,所以在手机app上也就没有必要实现这个service。
用 WearableListenerService你可以监听以下事件:
-
onDataChanged():无论是创建,删除或改变一个data item,这个回调函数就会在所有网络节点被触发(互相连接的设备被抽象为网络节点,这在之前章节有描述过)
-
onMessageReceived():收到一个Message,这是专门对目标节点会触发的事件。
-
onCapabilityChanged():当你的一个app广播自身能力变化的时候,这个事件将会触发。如果你在探索邻近节点的时候,你可以调用isNearby来询问提供这个回调函数的节点。
另外,你可以用ChannelApit.CannelListener来监听管道事件,比如onChannelOpened().
创建WearableListenerService遵循以下步骤:
- 创建一个拓展了WearableListenerService的类。
- 监听你感兴趣的事件,比如onDataChanged().
3.在你的Android manifest中声明intent filter来告诉你系统的WearableListenerService.这个声明让系统可以在合适的事件绑定你的服务。
下面是一个实现了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);
}
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;
}
// 循环events并发送message给创建了data item的节点
for (DataEvent event : events) {
Uri uri = event.getDataItem().getUri();
// 从URI中获取节点id
String nodeId = uri.getHost();
// 将uri转换成二进制数组
byte[] payload = uri.toString().getBytes();
// 发送
Wearable.MessageApi.sendMessage(googleApiClient, nodeId,
DATA_ITEM_RECEIVED_PATH, payload);
}
}
}
使用filter
下面是一个WearableListenerService的intent filter:
<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>
在这个filter中,DATA_CHANGED
动作取代了之前推荐的BIND_LISTENER
,所以只有特定的事件才会启动你的程序。这个改变提升了系统的效率并减少了电池的消耗以及其他关于你的程序的日常管理费用。在上面的例子中,手表监听/start-activity
数据项。而手机监听/data-item-received
信息反馈。
标准的android 过滤器匹配规则会启动。你可以在manifest中指定多个services。每个service指定多个intent filter,一个filter中指定多个动作和数据段。filter可以匹配通配符主机或特定的逐句。为了匹配通配符主机,使用host="*"
.为了匹配特定的主机,指定host=<node_id>
.
你也可以匹配路径字符串或路径的前缀。如果你匹配路径或路径的前缀,你必须指定通配符主机或特定的助经济。如果你不指定,那么系统将会忽略你指定的路径。
如果想要了解更多关于手表上支持的过滤器类型,可以参考 WearableListenerService
上的API文档。
如果想要了解更多关于数据过滤器和匹配规则,可以参考 data
manifest元素的文档。
当匹配这些过滤器的时候,有两条规则需要牢记:
-
如果框架不支持intent filter,系统将会忽略所有其他的URI特性。
-
如果没有指定主机,系统会忽略所有的路径特性。
一个活动的监听器
如果你的app只在用户与app交互时关心数据层事件。它可能不需要长时间运行service来处理每个数据变化。在这样的例子中,你可以在activity中实现以下的接口来监听事件。
实现步骤如下:
-
实现想要的接口
-
在 onCreate()方法中创建GoogleApiClient的实例用于处理数据层API.
-
在 onStart()方法中调用connect()方法来连接Google Play 服务。
-
当连接已经稳定后,系统会调用onConnected()方法,在这里,你可以将[DataApi.addListener()
](https://developers.google.com/android/reference/com/google/android/gms/wearable/DataApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.DataApi.DataListener)),[MessageApi.addListener()
](https://developers.google.com/android/reference/com/google/android/gms/wearable/MessageApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.MessageApi.MessageListener, android.net.Uri, int)), 或 CapabilityApi.addListener()
附加到Google Play服务上来说明你感兴趣的数据层事件。 -
在onStop()方法中用 [DataApi.removeListener()
](https://developers.google.com/android/reference/com/google/android/gms/wearable/DataApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.DataApi.DataListener)), [MessageApi.removeListener()
](https://developers.google.com/android/reference/com/google/android/gms/wearable/MessageApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.MessageApi.MessageListener)), 或 [CapabilityApi.removeListener()
](https://developers.google.com/android/reference/com/google/android/gms/wearable/CapabilityApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.CapabilityApi.CapabilityListener))方法来移除注册。
或者你也可以在onResume()方法中添加监听器,在onPause()方法中取消注册,这样你就可以仅在activity在前台的时候接收数据层事件。 -
实现 onDataChanged()
, onMessageReceived()
, onCapabilityChanged()
或其他的一些在 Channel API listener methods中的方法,这取决于你想要实现的功能。
下面是实现 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());
}
}
}
}
对正在运行的监听器使用filters
就想你可以对在manifest-based的WearableListenerService
指定intent filter一样,你也可以在注册可穿戴设备API的监听器的时候使用intent filters。相同的规则会同时对manifest-based和API-based的监听器有效。
一个通用的模式是在activity的onResume()
中注册一个指定了特定path或path的前缀的监听器,并在onPause()
方法中移除监听器。在这种模式下使用监听器允许你的程序更有选择的接受事件,提升它的设计和效率
网友评论