Watch開發(fā)的學(xué)習(xí)結(jié)構(gòu)
1. 創(chuàng)建Notification
2. 創(chuàng)建自定義的UI
3. 發(fā)送和同步數(shù)據(jù)
3.1訪問可穿戴數(shù)據(jù)層
調(diào)用數(shù)據(jù)層API,需創(chuàng)建如下實例:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addOnConnectionFailedListener(this)
.addConnectionCallbacks(this)
.build();
第二步:建議在onResume方法中調(diào)用GoogleApiClient.connect()進行連接:
protected void onResume() {
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
super.onResume();
}
第三步:當我們退出當前界面扎狱,建議斷開連接:
@Override
protected void onPause() {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
完成上面三個步驟概耻,我們就完成了數(shù)據(jù)層客戶端的創(chuàng)建、連接和斷開哑芹。
客戶端連接時我們需要設(shè)置兩個監(jiān)聽器,一個是連接成功的監(jiān)聽,另一個是連接失敗的監(jiān)聽干茉。
實現(xiàn) GoogleApiClient.ConnectionCallbacks:
#連接成功回調(diào)
public void onConnected(@Nullable Bundle bundle) {
}
#連接暫停回調(diào)
public void onConnectionSuspended(int i) {
Log.e(TAG, "connect sucssed : "+i);
mNode=null;
}
實現(xiàn) GoogleApiClient.OnConnectionFailedListener:
#連接失敗回調(diào)
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
當我們調(diào)用GoogleApiClient.connect()方法連接之后很泊,會調(diào)用以上回調(diào)角虫,反饋連接客戶端的結(jié)果沾谓,連接成功之后我們可以做一些操作,比如:獲取Node節(jié)點等戳鹅。
3.2 同步數(shù)據(jù)單元(Data Map 支持基本類型和String類型)
問題一:可穿戴設(shè)備作為發(fā)送方時響應(yīng)發(fā)送成功均驶,但是其實未成功。
發(fā)送數(shù)據(jù)(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<DataApi.DataItemResult>() {
@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());
}
}
});
接受數(shù)據(jù):
實現(xiàn)WearableListenerService服務(wù)的實現(xiàn)類
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中實現(xiàn)DataApi.DataListener枫虏,客戶端連接成功后使用Wearable.DataApi.addListener(mGoogleApiClient, this);添加監(jiān)聽器妇穴。
3.3傳輸資源
本地資源轉(zhuǎn)化為Bitmap:
Bitmap bmp= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Bitmap轉(zhuǎn)成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 發(fā)送 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<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.e(TAG, "Sending image was successful: " + dataItemResult.getStatus()
.isSuccess());
}
});
發(fā)送成功后處理回調(diào):
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發(fā)送與接收消息
使用 MessageApi 發(fā)送消息伟骨,不像數(shù)據(jù)元的同步,Messages是單向交流機制燃异,這有利于遠程進程調(diào)用(RPC)携狭,比如:發(fā)送消息到可穿戴設(shè)備以開啟activity。
發(fā)送消息之前回俐,我們得先確定發(fā)送通知的節(jié)點逛腿,可通過兩種方法獲取:
方法一:
private Collection<String> getNodes() {
HashSet<String> results = new HashSet<>();
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for (Node node : nodes.getNodes()) {
results.add(node.getId());
}
return results;
}
通過廣播獲取節(jié)點:
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(NodeApi.GetConnectedNodesResult nodes) {
for (Node node : nodes.getNodes()) {
mNode = node;
}
}
});
發(fā)送消息如下:
發(fā)送消息之前先判斷是否有節(jié)點仅颇,或者是否客戶端連接
if(null!=mGoogleApiClient&&null!=mNode){
Wearable.MessageApi.sendMessage(mGoogleApiClient,mNode.getId(),START_ACTIVITY_PATH,new
byte[0]).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
@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實現(xiàn)MessageListener ,通過 MessageApi.addListener()添加和MessageApi.removeListener()刪除監(jiān)聽器单默。
方法二:通過繼承WearableListenerService的服務(wù)。
回調(diào)都是如下方法:
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來判斷我們的行為搁廓,通過可穿戴設(shè)備啟動手執(zhí)設(shè)備的界面。
messageEvent.getData()可以獲取我們傳輸?shù)臄?shù)據(jù)耕皮,記得byte[]數(shù)組轉(zhuǎn)化境蜕。