一. 前言

背景

一开始笔者在研究数据发送与接收的时候,看到Wear数据类DataMap除了可以put基本类型外,还有个fromBundle方法来构建一个DataMap对象。所以一口气的将原本功能上的序列化对象传递过去,结果手表端一直都收不到消息。

问题原因

后来查阅了开发者文档,发现这个Bundle并没有我们在Intent中传递数据的那么强大,它并不支持序列化!先附上开发者文档的说明:

Returns a DataMap from a Bundle. The input Bundle is expected to contain only elements supported by DataMap. Any elements in the Bundle not supported by DataMap will be dropped.
http://developer.android.com/reference/com/google/android/gms/wearable/DataMap.html#fromBundle(android.os.Bundle)

关键的一句是"The input Bundle is expected to contain only elements supported by DataMap",只有DataMap本身支持的类型才能被传递到Bundle中,那么也就是说我们自己构建的数据Bean并不能够直接序列化传进Bundle中,这导致结果是"Any elements in the Bundle not supported by DataMap will be dropped",即这些数据不会被传递,而是会被抛弃。

问题来了

那么,问题来了!怎么样才能够优雅地传递数据Bean呢?
接下来笔者将给出自己的解决方案。

二. 解决方案

1. 使用公共工程

  1. 创建公共工程:因为数据在Phone工程Wear工程是共用,为了避免在这两个工程中都各自持有数据类,最好的方式自然是将这部分抽出来。创建完毕后,打钩"Is Library",将公共工程设置为库工程。
  2. 导入公共工程:Phone工程Wear工程都引用公共工程。
  3. 公共工程模板:以下用一个城市数据作为样例。注意:要使用DataMap这个类,必须引用5.0版本以上的GooglePlayServices。

import com.google.android.gms.wearable.DataMap;
public class WearCityBean { public static final String KEY = "/bean/wear/city";
private static final String M_CITY_ID = "mCityId";
private static final String M_CITY_NAME = "mCityName";
private static final String M_COUNTRY_NAME = "mCountryName";
// 城市ID
private String mCityId;
// 城市名
private String mCityName;
// 国家名
private String mCountryName; public WearCityBean() { } public WearCityBean(DataMap map) {
setCityId(map.getString(M_CITY_ID));
setCityName(map.getString(M_CITY_NAME));
setCountryName(map.getString(M_COUNTRY_NAME)); } public DataMap getDataMap() {
DataMap map = new DataMap();
map.putString(M_CITY_ID, mCityId);
map.putString(M_CITY_NAME, mCityName);
map.putString(M_COUNTRY_NAME, mCountryName);
return map;
} public String getCityId() {
return mCityId;
} public void setCityId(String cityId) {
mCityId = cityId;
} public String getCityName() {
return mCityName;
} public void setCityName(String cityName) {
mCityName = cityName;
} public String getCountryName() {
return mCountryName;
} public void setCountryName(String countryName) {
mCountryName = countryName;
} @Override
public String toString() {
return "WearCityBean [mCityId=" + mCityId + ", mCityName=" + mCityName
+ ", mCountryName=" + mCountryName + "]";
}
}

关键代码分析 - 发送数据:要发送数据的一端,将一个DataMap对象传入到这个方法中,将Bean自身的基本数据传递到DataMap中。这样,要发送数据的那一端就不用存在很多零散的代码,而且如果Phone端和Wear端都要实现数据发送的话,就不用重复两份代码了。

public DataMap getDataMap() {
DataMap map = new DataMap();
map.putString(M_CITY_ID, mCityId);
map.putString(M_CITY_NAME, mCityName);
map.putString(M_COUNTRY_NAME, mCountryName);
return map;
}

发送端代码:下面通过先初始化一个WearCityBean对象后,再从中获取DataMap对象,最后再放到数据请求对象PutDataMapRequest中,完成发送的封装。

private void packageCityData(PutDataMapRequest dataMap) {
//通过getWearCityBean()构建并初始化数据对象
WearCityBean wearCityBean = getWearCityBean();
DataMap map = wearCityBean.getDataMap();
dataMap.getDataMap().putDataMap(WearCityBean.KEY, map);
}

关键代码分析 - 接收数据:将收到的DataMap用来构建一个WearCityBean对象,即可完成数据的解析。

public WearCityBean(DataMap map) {
setCityId(map.getString(M_CITY_ID));
setCityName(map.getString(M_CITY_NAME));
setCountryName(map.getString(M_COUNTRY_NAME));
}
  1. 接收端的代码过于简单,就不再附上了。

后话

  • 以上是笔者在API不够满足需求的情况下想出的一套解决方案,经过多次测试,运行良好。
  • 除了直接的将基本数据类型传入DataMap中之外,还可以用Json或者其他方式将数据封装成一个String,再传入到DataMap中。这也是一个不错的方案。

Android Wear开发 - 数据通讯 - 第四节 : 数据封装(解决不能序列化问题)的更多相关文章

  1. Android Wear开发 - 数据通讯 - 第零节 : 打包Wear应用(手机和手表应用如何连接)

    之所以将打包这一特殊的内容作为数据通讯的第零节,是因为如果没有通过配置打包的一些信息,则没有办法将手机端应用和手表端应用连接起来,则无法继续进行接下来的数据通讯的开发. 以下依然只针对Eclipse平 ...

  2. Android Wear开发 - 数据通讯 - 第二节 : 数据的发送与接收

    本节由介绍3种数据的发送接收:1.Data Items : 比特类型数据,限制100KB以内2.Assets : 资源类型数据,大小无上限3.Message : 发送消息,触发指令 http://de ...

  3. Android Wear开发 - 数据通讯 - 第一节 : 连接数据层

    http://developer.android.com/training/wearables/data-layer/accessing.html Accessing the Wearable Dat ...

  4. Android Wear开发 - 数据通讯 - 第三节 : 事件处理

    http://developer.android.com/training/wearables/data-layer/events.html 以下是本人在学习官方开发文档时的笔记,主要是翻译为主,并在 ...

  5. Android Wear开发

    Android Wear从2014年3月发布到现在已经从1.0发展到2.0(目前还没正式发布).其产品定位也发化了巨大变化,因为Android Wear 1.0通讯方式只有蓝牙,限定了系统,比较依赖手 ...

  6. Android Wear 开发入门

    大家好,我是陆嘉杰,我是一名Android开发者.我想和大家进行一些技术交流,希望越来越多的人能和我成为好朋友. 大家都知道,智能手表是下一个开发的风口,而这方面的技术又属于前沿,所以和大家分享下An ...

  7. IDEA搭建Android wear开发环境,Android wear,I'm comming!

    随着google公布了android wear这个东西.然后又有了三星的gear,LG的G watch以及moto 360,苹果由公布了apple watch.未来可能在智能手表行业又有一场战争. 当 ...

  8. Android Wear开发 - 卡片通知 - 第一节 : 添加Android Wear通知特性

    一. 前言说明 Android Wear大部分显示形式是卡片的形式,而最简单地支持Android Wear方式就是用通知**Notification**.而实现最简单的,非高度自定义的通知,则只需要在 ...

  9. Android Wear开发 - 卡片通知 - 第二节 : 自定义Wear卡片样式

    一.前言说明 在上一节添加Android Wear通知特性我们实现了简单的Android Wear卡片拓展,但是默认提供给我们的多张卡片只能实现简单的文字展示,如果想要自定义布局,添加图片等等,则需要 ...

随机推荐

  1. ios从相册:摄像头中获取视频

    ios从相册/摄像头中获取视频 如何从相册中获取视频 使用的是一个和获取照片相同的类UIImagePickerController //相册中获取视频 - (IBAction)clickViedoOF ...

  2. CentOS 6.3 源码安装LAMP(Linux+Apache+Mysql+Php)环境

    一.简介 什么是LAMP LAMP是一种Web网络应用和开发环境,是Linux, Apache, MySQL, Php/Perl的缩写,每一个字母代表了一个组件,每个组件就其本身而>言都是在它所 ...

  3. display:table- cell属性的练习

    display:table- cell属性指让标签元素以表格单元格的形式呈现,类似于td标签.目前IE8+以及其他现代浏览器都是支持此属性的,但是IE6/7只能对你说 sorry了,这一事实也是大大制 ...

  4. discuz论坛几种安全策略(二)

    大头看了我给的方案,http://www.cnblogs.com/itsmylife/p/4012000.html 今早给的回复如下: “ 补充几点,供参考: 第一条,配置一下允许上传文件的格式以及大 ...

  5. c读mysql产生乱码问题

    在编写接口API时,发现中文字utf8输入的在linux下采用c读取显示为”??”问号,这是由于编码造成的. 很简单的两个地方做修改就搞定. 1.先找到mysql的my.cnf配置文件/etc/my. ...

  6. Bash常用快捷键

    快捷键 作用 Ctrl+A 把光标移动到命令行开头,如果我们输入的命令过长,想要把光标移动到命令行开头时使用 Ctrl+E 把光标移动到命令行结尾 Ctrl+C 强制终止当前的命令 Ctrl+L 清屏 ...

  7. metalink下载补丁包

    以下截图 截取自 某 升级包中携带的 readme文档 把以上图片转换为 文字 Download and Install Patch Updates Refer to the My Oracle Su ...

  8. [C++]C++类基本语法

    本测试代码包括以下内容: (1)如何使用构造函数:(2)默认构造函数:(3)对象间赋值:(4)const使用语法:(5)定义类常量: 一种方法是用enum,另一种方法是使用static. #inclu ...

  9. cmd 命令行下复制、粘贴的快捷键

    1.单击左下角“开始”菜单,选择“运行”,输入“cmd”. 2.在弹出的cmd窗口的标题栏上点击“右键”,选择“属性”. 3.在弹出的对话框中选择“选项”这个选项卡,在“编辑选项”区域中勾选“快速编辑 ...

  10. java.math.BigDecimal类

    BigDecimal类用于高精度计算.一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecima ...