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。

Android 建立手机与手表数据同步机制总结的更多相关文章

  1. Android 12(S) 图像显示系统 - GraphicBuffer同步机制 - Fence

    必读: Android 12(S) 图像显示系统 - 开篇 一.前言 前面的文章中讲解Android BufferQueue的机制时,有遇到过Fence,但没有具体讲解.这篇文章,就针对Fence这种 ...

  2. 23、redis如何实现主从复制?以及数据同步机制?

    redis主从复制 和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或 ...

  3. MySQL-技术专题-MySQL主从架构以及[半同步机制]模式大全

    MySQL的主从复制 一般在大规模的项目上,都是使用MySQL的复制功能来创建MySQL的主从集群的. 主要是可以通过为数据库服务器配置一个或多个备库的方式来进行数据同步. 复制的功能不仅有利于构建高 ...

  4. Zookeeper的选举机制和同步机制超详细讲解,面试经常问到!

    前言 zookeeper相信大家都不陌生,很多分布式中间件都利用zk来提供分布式一致性协调的特性.dubbo官方推荐使用zk作为注册中心,zk也是hadoop和Hbase的重要组件.其他知名的开源中间 ...

  5. Redis面试热点工程架构篇之数据同步

    温馨提示 更佳阅读体验:[决战西二旗]|Redis面试热点之工程架构篇[2] 前言 前面用了3篇文章介绍了一些底层实现和工程架构相关的问题,鉴于Redis的热点问题还是比较多的,因此今天继续来看工程架 ...

  6. Android利用Fiddler进行网络数据抓包,手机抓包工具汇总

    Fiddler抓包工具 Fiddler抓包工具很好用的,它可以干嘛用呢,举个简单例子,当你浏览网页时,网页中有段视频非常好,但网站又不提供下载,用迅雷下载你又找不到下载地址,这个时候,Fiddler抓 ...

  7. Android利用Fiddler进行网络数据抓包,手机抓包工具汇总,使用mono运行filddler

    Fiddler抓包工具 Fiddler抓包工具很好用的,它可以干嘛用呢,举个简单例子,当你浏览网页时,网页中有段视频非常好,但网站又不提供下载,用迅雷下载你又找不到下载地址,这个时候,Fiddler抓 ...

  8. Android 音视频同步机制

    一.概述 音视频同步(avsync),是影响多媒体应用体验质量的一个重要因素.而我们在看到音视频同步的时候,最先想到的就是对齐两者的pts,但是实际使用中的各类播放器,其音视频同步机制都比这些复杂的多 ...

  9. redis多实例与主从同步及高级特性(数据过期机制,持久化存储)

    redis多实例 创建redis的存储目录 vim /usr/local/redis/conf/redis.conf #修改redis的配置文件 dir /data/redis/ #将存储路径配置修改 ...

随机推荐

  1. IntelliJ IDEA2018.1、2017.3激活

    IntelliJ IDEA2018.1.2017.3破解教程 http://idea.java.sx/ 简单快捷!! ————————————————————————————————————————  ...

  2. Android Activity之间切换出现短暂黑屏的处理方法

    转自:http://www.cppblog.com/fwxjj/archive/2013/01/14/197259.html 在默认情况下,Android应用程序启动时,会有一个黑屏的时期,原因是,首 ...

  3. PHP开发微信被动回复消息遇到的大坑

    最近开始做CMS后台与微信公众号的整合,在做被动回复消息时,按照官方文档的XML格式回复消息,总是提示"该公众号提供的服务出现故障,请稍后再试".但是通过微信提供的接口调试工具看我 ...

  4. Spearman Rank(斯皮尔曼等级)相关系数

    转自:http://blog.csdn.net/wsywl/article/details/5859751 1.简介 在统计学中,斯皮尔曼等级相关系数以Charles Spearman命名,并经常用希 ...

  5. libnids使用举例

    ---[[ libnids应用实例 ]]---------------------------------- 1.nids_next()函数的应用 ========================== ...

  6. Search Insert Position leetcode java

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  7. 七牛云存储 qiniu 域名 回收 文件上传 备份 下载 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. 判断小米 魅族 华为 系统 MIUI EMUI FLYME

    获取系统信息 public class SimpleDeviceUtils { public enum SystemType { /** * 小米手机(MIUI系统) */ SYS_MIUI, /** ...

  9. thinkphp生成的验证码不显示问题解决

    在调用验证码之前加上 ob_clean(); 不显示验证码的代码: public function verify(){ $verify = new \Think\Verify(); $verify-& ...

  10. 老猪带你玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...