Watch开发的学习结构
1. 创建Notification
2. 创建自定义的UI
3. 发送和同步数据
3.1访问可穿戴数据层
调用数据层API,需创建如下实例:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addOnConnectionFailedListener(this)
.addConnectionCallbacks(this)
.build();
第二步:建议在onResume方法中调用GoogleApiClient.connect()进行连接:
protected void onResume() {
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
super.onResume();
}
第三步:当我们退出当前界面,建议断开连接:
@Override
protected void onPause() {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
完成上面三个步骤,我们就完成了数据层客户端的创建、连接和断开。
客户端连接时我们需要设置两个监听器,一个是连接成功的监听,另一个是连接失败的监听。
实现 GoogleApiClient.ConnectionCallbacks:
#连接成功回调
public void onConnected(@Nullable Bundle bundle) {
}
#连接暂停回调
public void onConnectionSuspended(int i) {
Log.e(TAG, "connect sucssed : "+i);
mNode=null;
}
实现 GoogleApiClient.OnConnectionFailedListener:
#连接失败回调
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
当我们调用GoogleApiClient.connect()方法连接之后,会调用以上回调,反馈连接客户端的结果,连接成功之后我们可以做一些操作,比如:获取Node节点等。
3.2 同步数据单元(Data Map 支持基本类型和String类型)
问题一:可穿戴设备作为发送方时响应发送成功,但是其实未成功。
发送数据(Data Map):
PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(COUNT_PATH);
putDataMapRequest.getDataMap().putInt(COUNT_KEY, count++);
PutDataRequest request = putDataMapRequest.asPutDataRequest();
request.setUrgent();
Log.i(TAG, "Generating DataItem: " + request);
if (!mGoogleApiClient.isConnected()) {
return;
}
Wearable.DataApi.putDataItem(mGoogleApiClient, request)
.setResultCallback(new ResultCallback() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
if (!dataItemResult.getStatus().isSuccess()) {
Log.e(TAG, "ERROR: failed to putDataItem, status code: "
+ dataItemResult.getStatus().getStatusCode());
}else{
Log.e(TAG, "Success: "
+ dataItemResult.getStatus().getStatusCode());
}
}
});
接受数据:
实现WearableListenerService服务的实现类
public void onDataChanged(DataEventBuffer dataEvents) {
Log.e(TAG, "onDataChanged: " + dataEvents);
Log.d(TAG, "onDataChanged22: " + dataEvents+"--");
// Loop through the events and send a message back to the node that created the data item.
for (DataEvent event : dataEvents) {
Uri uri = event.getDataItem().getUri();
String path = uri.getPath();
if (COUNT_PATH.equals(path)) {
// Get the node id of the node that created the data item from the host portion 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();
DataMap dataMap= DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
Log.d(TAG, "updateCount: " +dataMap.getInt(COUNT_KEY));
Log.d(TAG, "updateString: " +dataMap.getString(STRING_KEY));
}
}
}
或者activity中实现DataApi.DataListener,客户端连接成功后使用Wearable.DataApi.addListener(mGoogleApiClient, this);添加监听器。
3.3传输资源
本地资源转化为Bitmap:
Bitmap bmp= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Bitmap转成Asset:
private static Asset toAsset(Bitmap bitmap) {
ByteArrayOutputStream byteStream = null;
try {
byteStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
return Asset.createFromBytes(byteStream.toByteArray());
} finally {
if (null != byteStream) {
try {
byteStream.close();
} catch (IOException e) {
// ignore
}
}
}
}
然后使用Data Map 发送 Asset:
PutDataMapRequest dataMap = PutDataMapRequest.create(IMAGE_PATH);
dataMap.getDataMap().putAsset(IMAGE_KEY, asset);
dataMap.getDataMap().putLong("time", new Date().getTime());
PutDataRequest request = dataMap.asPutDataRequest();
request.setUrgent();
Wearable.DataApi.putDataItem(mGoogleApiClient, request)
.setResultCallback(new ResultCallback() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.e(TAG, "Sending image was successful: " + dataItemResult.getStatus()
.isSuccess());
}
});
发送成功后处理回调:
public void onDataChanged(DataEventBuffer dataEventBuffer) {
for (DataEvent event:dataEventBuffer){
if (event.getType()==DataEvent.TYPE_CHANGED&&event.getDataItem().getUri().getPath().equals("/image")){
DataMapItem dataMapItem=DataMapItem.fromDataItem(event.getDataItem());
final Asset profileAsset=dataMapItem.getDataMap().getAsset("image");
new Thread(new Runnable() {
@Override
public void run() {
final Bitmap bitmap=loadBitmapFromAsset(profileAsset);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (bitmap!=null&&mImageView!=null){
mImageView.setImageBitmap(bitmap);
}
}
});
}
}).start();
}
}
}
loadBitmapFromAsset方法如下,并且必须在子线程中运行:
public Bitmap loadBitmapFromAsset(Asset asset) {
if (asset == null) {
throw new IllegalArgumentException("Asset must be non-null");
}
ConnectionResult result =
mGoogleApiClient.blockingConnect(5, TimeUnit.MILLISECONDS);
if (!result.isSuccess()) {
return null;
}
// convert asset into a file descriptor and block until it's ready
InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
mGoogleApiClient, asset).await().getInputStream();
mGoogleApiClient.disconnect();
if (assetInputStream == null) {
Log.w(TAG, "Requested an unknown Asset.");
return null;
}
// decode the stream into a bitmap
return BitmapFactory.decodeStream(assetInputStream);
}
以上步骤就能完成一个图片的传输了。
3.4发送与接收消息
使用 MessageApi 发送消息,不像数据元的同步,Messages是单向交流机制,这有利于远程进程调用(RPC),比如:发送消息到可穿戴设备以开启activity。
发送消息之前,我们得先确定发送通知的节点,可通过两种方法获取:
方法一:
private Collection getNodes() {
HashSet results = new HashSet<>();
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for (Node node : nodes.getNodes()) {
results.add(node.getId());
}
return results;
}
通过广播获取节点:
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback() {
@Override
public void onResult(NodeApi.GetConnectedNodesResult nodes) {
for (Node node : nodes.getNodes()) {
mNode = node;
}
}
});
发送消息如下:
发送消息之前先判断是否有节点,或者是否客户端连接
if(null!=mGoogleApiClient&&null!=mNode){
Wearable.MessageApi.sendMessage(mGoogleApiClient,mNode.getId(),START_ACTIVITY_PATH,new
byte[0]).setResultCallback(new ResultCallback() {
@Override
public void onResult(@NonNull MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e("TAG", "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
}else{
Log.i("TAG", " send message 成功");
}
}
});
}
下面我们来说一下接收消息的两种方法:
方法一:通过Activity实现MessageListener ,通过 MessageApi.addListener()添加和MessageApi.removeListener()删除监听器。
方法二:通过继承WearableListenerService的服务。
回调都是如下方法:
public void onMessageReceived(MessageEvent messageEvent) {
LOGD(TAG, "onMessageReceived: " + messageEvent);
Log.d(TAG, "onDataChanged22: " + messageEvent.getData());
// Check to see if the message is to start an activity
if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
Intent startIntent = new Intent(this, MainTestActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startIntent);
}
}
由此可知,我们可以通过path来判断我们的行为,通过可穿戴设备启动手执设备的界面。
messageEvent.getData()可以获取我们传输的数据,记得byte[]数组转化。