处理数据层的事件
因为数据层在手持和可穿戴设备间同步并发送数据,所以通常要监听重要事件,例如创建数据元,接受消息,或当可穿戴设备和手机连接时。
对于监听数据层事件,有两种选择:
- 创建一个继承自WearableListenerService的service。
- 创建一个实现DataApi.DataListener接口的activity。
通过这两种选择,你覆写任何你关心的数据事件回调方法来处理您的实现。
使用 WearableListenerService
典型地,在你的手持设备和可穿戴设备上都创建该service实例。如果你不关心其中一个应用中的数据事件,就不需要在相应的应用中实现此service。
例如,您可以在一个手持设备应用程序上操作数据元对象,可穿戴设备的应用监听这些更新并更新UI。而可穿戴不更新任何数据元,所以手持设备的应用不监听任何可穿戴式设备应用的数据事件。
你可以用 WearableListenerService监听如下事件:
- onDataChanged()) - 当数据元对象创建,更改,删除时调用。一连接端的事件将触发两端的回调方法。
- onMessageReceived()) - 消息从一连接端发出时在另一连接端触发此回调方法。
- onPeerConnected()) 和 onPeerDisconnected()) - 当与手持或可穿戴设备连接或断开时调用。一连接端连接状态的改变会在两端触发此回调方法。
创建WearableListenerService:
- 创建一个继承自WearableListenerService的类。
- 监听你关心的事件,比如onDataChanged()。
- 在Android manifest中声明一个intent filter,通知系统你的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);
}
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);
}
}
}
这是Android mainfest中相应的intent filter:
数据层回调权限
为了在数据层事件上向你的程序提供回调方法,Google Play services 绑定到你的WearableListenerService,通过IPC调用回调方法。这样的结果是,你的回调方法继承了调用进程的权限。
如果你想在一个回调中执行权限操作,安全检查会失败,因为你的回调是以调用进程的身份运行,而不是应用程序进程的身份运行。
为了解决这个问题,在进入IPC后使用clearCallingIdentity())重置身份,当你完成权限操作后,使用restoreCallingIdentity())恢复身份:
long token = Binder.clearCallingIdentity();
try {
performOperationRequiringPermissions();
} finally {
Binder.restoreCallingIdentity(token);
}
使用监听者 Activity
如果你的应用只关心当用户与应用交互时产生的数据层事件,并且不需要一个长时间运行的service来处理每一次数据的改变,那么你可以在一个activity中通过实现如下一个和多个接口监听事件:
- DataApi.DataListener
- MessageApi.MessageListener
- NodeApi.NodeListener
如何创建一个activity监听数据事件:
- 实现所需的接口。
- 在onCreate(Bundle)中创建 GoogleApiClient实例。
- 在onStart()中调用connect() 将客户端连接到 Google Play services。
- 当连接到Google Play services后,系统调用 onConnected()。这里你调用DataApi.addListener(), MessageApi.addListener(), 或 NodeApi.addListener()以告知Google Play services,你的activity要监听数据层事件。
- 在 onStop()中,用 DataApi.removeListener(), MessageApi.removeListener()或NodeApi.removeListener() 注销监听。
- 基于你实现的接口继而实现 onDataChanged(), onMessageReceived(), onPeerConnected()和 onPeerDisconnected()。
这是实现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());
}
}
}
}