Android 建立手機與手表數據同步機制總結


Android Wear 數據同步機制總結

當手機與手表建立藍牙連接之后。數據就能夠通過Google Play Service進行傳輸。

同步數據對象Data Item

DataItem提供手機與手表數據存儲的自己主動同步,一個DataItem對象由其創建者與路徑組成的URI所確定。一個DataItem對象為手機和手表提供了一個數據通路,開發人員通過改變指定的DataItem實現手機和手表的數據自己主動同步。

訪問數據層API

DataItem能夠提供手機和手表數據的保存,改變該對象的操作則依賴數據層API(the Data Layer APIs)。也就是說,在改變DataItem數據之前,須要先訪問數據層,獲得一個GoogleApiClient實例,從而能夠使用數據層API。

以下是實例化GoogleApiClient的代碼

GoogleApiClient mGoogleAppiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(new ConnectionCallbacks() {
               @Override
               public void onConnected(Bundle connectionHint) {
                   Log.d(TAG, "onConnected: " + connectionHint);
                   // Now you canuse the data layer API
               }
               @Override
               public void onConnectionSuspended(int cause) {
                   Log.d(TAG, "onConnectionSuspended: " + cause);
               }
        })
        .addOnConnectionFailedListener(new OnConnectionFailedListener() {
               @Override
               public void onConnectionFailed(ConnectionResult result) {
                   Log.d(TAG, "onConnectionFailed: " + result);
               }
            })
        .addApi(Wearable.API)
        .build();

在使用數據層Api的之前。須要先調用connect()方法。假設成功則會回調onConnected()方法,否則回調onConnectionFailed()。

同步DataItems

GoogleApiClient連接成功后。就能夠通過DataItem進行數據同步了。

一個DataItem包括連個部分,一個是Payload,這是一個字節數組,能夠通過序列化或者反序列化保存須要的數據類型和對象;還有一個是Path,這是一個唯一的字符串,由反斜杠開頭,差別不同的DataItem。

         通常在開發過程中是使用DataMap類實現DataItem接口。相似Bundle鍵值對的存儲方式。

         以下是使用的DataMap步驟:

1、  創建PutDataMapRequest對象,為DataItem設置path值;

2、  使用put…()方法為DataMap設置須要的數據;

3、  調用PutDataMapRequest.asPutDataRequest()創建PutDataRequest對象。

4、  調用DataApi.putDataItem()請求系統創建DataItem。

假設此時手機和手表沒有建立連接。則會將數據保存在Buffer中,等下次連接后會發送到還有一方。

以下是使用DataMap創建DataItem的方法

 
         
PutDataMapRequest dataMap = PutDataMapRequest.create("/count");
dataMap.getDataMap().putInt(COUNT_KEY, count++);
PutDataRequest request = dataMap.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi
        .putDataItem(mGoogleApiClient, request);

監聽數據層事件

因為數據層同步或發送的數據連接手機和手表,所以常常須要獲知何時DataItem被創建以及手機與手表什么時候連接或斷開等事件。

監聽數據層時間能夠使用兩種方式,一種是繼承WearableListenerService。一種是在Activity中實現DataApi.DataListener。不管使用兩種方式的哪種。能夠重寫其須要的回調方法運行對應的操作。

1、  使用WearableListenerService

該service在手機和手表端都能夠使用,假設在一方不須要監聽數據層時間能夠不適用該服務。

比如,能夠在手機端接收和設置DataItem。然后在手表端實現該服務,監聽數據層的事件,從而改動手表的UI。

WearableListenerService提供回調接口onDataChanged()處理DataItem的變化,當DataItem被創建、更改或刪除,手機和手表的該事件將被觸發。

以下是使用WearableListenerService的方法

1、  創建一個類繼承WearableListenerService;

2、  監聽須要的事件,如onDataChanged()。

3、  在配置文件里聲明一個intentfilter通知系統監聽WearableListenerService,這樣在系統須要的時候就會綁定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;
        }

        // 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);
        }
    }
}

以下代碼是配置文件里聲明的intentfilter

 
         
<service android:name=".DataLayerListenerService">
  <intent-filter>
      <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
  </intent-filter>
</service>

使用DataApi.DataListener監聽數據層

假設不須要后台長時間進行監聽,能夠使用DataApi.DataListener進行監聽。以下是使用該方式的方法。

1、  使用DataApi.DataListener接口

2、  在onCreate中創建 GoogleApiClient。訪問數據層API

3、  在onStart中調用connect()連接Google PlayService

4、  但連接上GooglePlay Service后,系統調用onConnected(),通知Google Play service該activity監聽數據層事件

5、  在onStop中調用DataApi.removeListener()

6、  實現 onDataChanged()回調

以下是使用DataApi.DataListener監聽數據層事件的代碼

 
         
public class MainActivity extends Activity implements
        DataApi.DataListener, ConnectionCallbacks, OnConnectionFailedListener {

    @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());
            }
        }
    }

獲取手機通知大家的服務

Android提供了一個服務類接口NotificationListenerService,繼承該服務,能夠獲取手機中應用發起的通知。在配置文件里須要加入例如以下聲明和權限

 
         
<service android:name=".NotificationListener"  
         android:label="@string/service_name"  
         android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">  
    <intent-filter>  
        <action android:name="android.service.notification.NotificationListenerService" />  
    </intent-filter>  
</service>  

這樣在系統設置中會出現一個是否同意該服務捕獲通知的選項。在設置--安全與隱私--通知讀取權限

該服務有兩個抽象方法須要實現,各自是當有通知發起與通知被銷毀,都會觸發其回調方法。

 
         
public class NotificationCollectorService extends NotificationListenerService {  
  
    @Override  
    public void onNotificationPosted(StatusBarNotification sbn) { 
    }   
    @Override  
    public void onNotificationRemoved(StatusBarNotification sbn) {  
    }  
}  

也就是說當系統發現某應用產生通知或者用戶刪除某通知,都會回調該服務的這兩個函數。函數的參數StatusBarNotification包括着該通知的詳細信息。

假設是在Android Wear開發中。使用該方法捕獲手機的通知,然后同步到手表中。就是使用該服務進行的中轉。

通知同步

接收到的通知以StatusBarNotification對象形式傳遞給回調函數onNotificationPosted(),

調用StatusBarNotification對象的公共方法,分別取出StatusBarNotification中的PackageName、Tag、Id、notification對象和PostTime。通過這些值去創建DataItem。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM