zoukankan      html  css  js  c++  java
  • 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。


  • 相关阅读:
    Objective-C基础教程读书笔记(6)
    Objective-C基础教程读书笔记(7)
    [置顶] android网络通讯之HttpClient4不指定参数名发送Post
    一些常见的正在表达式
    给EditText中的图片加监听
    HDU 4569Special equations2012长沙邀请赛E题(数学知识)
    Linux malloc大内存的方法
    优秀员工的做法-领先的专业、道路管理
    ZOJ 3324 Machine
    DateUtil
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8413679.html
Copyright © 2011-2022 走看看