W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
編寫:wly2014 - 原文: http://developer.android.com/training/wearables/data-layer/events.html
當做出數(shù)據(jù)層上的調(diào)用時,我們可以得到它完成后的調(diào)用狀態(tài),也可以用監(jiān)聽器監(jiān)聽到調(diào)用最終實現(xiàn)的改變。
注意到,調(diào)用數(shù)據(jù)層API,有時會返回 PendingResult,如 putDataItem()。PendingResult 一被創(chuàng)建,操作就會在后臺排列等候。之后我們?nèi)魺o動作,這些操作最終會默默完成。然而,通常要處理操作完成后的結(jié)果,PendingResult 能夠讓我們同步或異步地等待結(jié)果。
若代碼運行在主UI線程上,不要讓數(shù)據(jù)層API調(diào)用阻塞UI。我們可以增加一個回調(diào)到 PendingResult 對象來運行異步調(diào)用,該回調(diào)函數(shù)將在操作完成時觸發(fā)。
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());
}
}
});
如果代碼是運行在后臺服務(wù)的一個獨立的處理線程上(WearableListenerService的情況),則調(diào)用導致的阻塞沒影響。在這種情況下,我們可以用 PendingResult對象調(diào)用await()),它將阻塞至請求完成,并返回一個Result對象:
DataItemResult result = pendingResult.await();
if(result.getStatus().isSuccess()) {
Log.d(TAG, "Data item set: " + result.getDataItem().getUri());
}
因為數(shù)據(jù)層在手持和可穿戴設(shè)備間同步并發(fā)送數(shù)據(jù),所以通常要監(jiān)聽重要事件,例如創(chuàng)建數(shù)據(jù)元,接收消息,或連接可穿戴設(shè)備和手機。
對于監(jiān)聽數(shù)據(jù)層事件,有兩種選擇:
通過這兩種選擇,為我們感興趣的事件重寫數(shù)據(jù)事件回調(diào)方法。
通常,我們在手持設(shè)備和可穿戴設(shè)備上都創(chuàng)建該 service 的實例。如果我們不關(guān)心其中一個應(yīng)用中的數(shù)據(jù)事件,就不需要在相應(yīng)的應(yīng)用中實現(xiàn)此 service。
例如,我們可以在一個手持設(shè)備應(yīng)用程序上操作數(shù)據(jù)元對象,可穿戴設(shè)備應(yīng)用監(jiān)聽這些更新來更新自身的UI。而可穿戴不更新任何數(shù)據(jù)元,所以手持設(shè)備應(yīng)用不監(jiān)聽任何可穿戴式設(shè)備應(yīng)用的數(shù)據(jù)事件。
我們可以用 WearableListenerService 監(jiān)聽如下事件:
創(chuàng)建WearableListenerService,我們需要:
下例展示如何實現(xiàn)一個簡單的 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中相應(yīng)的intent filter:
<service android:name=".DataLayerListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
為了在數(shù)據(jù)層事件上向我們的應(yīng)用傳送回調(diào)方法,Google Play services 綁定到我們的WearableListenerService,并通過IPC調(diào)用回調(diào)方法。這樣的結(jié)果是,我們的回調(diào)方法繼承了調(diào)用進程的權(quán)限。
如果我們想在一個回調(diào)中執(zhí)行權(quán)限操作,安全檢查會失敗,因為回調(diào)是以調(diào)用進程的身份運行,而不是應(yīng)用程序進程的身份運行。
為了解決這個問題,在進入IPC后使用 clearCallingIdentity()) 重置身份,當完成權(quán)限操作后,使用 restoreCallingIdentity()) 恢復身份:
long token = Binder.clearCallingIdentity();
try {
performOperationRequiringPermissions();
} finally {
Binder.restoreCallingIdentity(token);
}
如果我們的應(yīng)用只關(guān)心當用戶與應(yīng)用交互時產(chǎn)生的數(shù)據(jù)層事件,并且不需要一個長時間運行的 service 來處理每一次數(shù)據(jù)的改變,那么我們可以在一個 activity 中通過實現(xiàn)如下一個和多個接口來監(jiān)聽事件:
創(chuàng)建一個 activity 監(jiān)聽數(shù)據(jù)事件,需要:
這是實現(xiàn)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());
}
}
}
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: