一、回顾 在分享这个项目之前先来回顾以前的三篇文章:
《基于即时通信和LBS技术的位置感知服务(一):提出问题及解决方案》(外网地址)
在第一篇文章中我们提出了要让A与B在不同地方能即刻获取对方准确位置的需求。之后讨论了解决这一问题做出的方案选择,即放弃使用轮询(Pooling) 的方式在不同客户端进行数据的更新,理由是因为B不知道A何时需要自己的位置信息,所以B只能一直post自己的位置数据给服务器,而A要定时通过 RESTful Web请求去服务器获取B的信息。
最后确定采用基于XMPP协议的PubSub(Publish/Subscribe,发布/订阅)方式进行异步消息实时传递。
《基于即时通信和LBS技术的位置感知服务(二):XMPP协议总结以及开源解决方案》(外网地址)
第二篇文章主要是对XMPP协议进行总结,以及为什么要采用XMPP,最后介绍了XMPP协议的Java开源解决方案:Openfire+Smack+Spark。
《基于即时通信和LBS技术的位置感知服务(三):搭建Openfire服务器+测试2款IM客户端》(外网地址)
第三篇文章详细讲解了基于XMPP协议的openfire服务架设,以及使用2款异构的基于XMPP协议的桌面客户端测试即时消息传递。
特别提示:为了更好的了解本项目要解决的问题,强烈建议去看看前面的三篇连载。
二、Location-Aware-Instant项目概括
Location-Aware-Instant是一个运行在Android OS 上具有位置即时感知功能的Android应用程序客户端。与之前第三篇文章里介绍了2款桌面程序一样,遵循开放标准的XMPP协议。
开发过程查找和参考了不少外文资料和相关项目,利用周末和晚上的时间、现在已经终于完成了90%。
本程序的架构和技术基础:
1. Android OS 应用开发技术:包括地图应用开发。
2. Openfire服务器:基于XMPP协议的开源Java服务器端程序。
3. Smack 开发库:对XMPP协议进行了封装的客户端实现的Java开发包。本项目采用的是ASmack Library(适合与Android OS 的Smack优化版)。
本项目的实现原理。共分三个层次:
1. 首先使用Openfire作为服务器,通过使用ASmack库开发出带有联系人列表的即时消息传递程序;
2. 然后客户端发送和接收消息之间植入自己的拦截预处理逻辑,并通过定制特殊的命令,实现消息的自动应答功能;
3. 最后一层在接收消息时,根据预处理命令判断是否对方的意图为定位请求,如果是则调用位置定位相关方法获取本地位置并自动恢复给发送请求一方,请求方根据预处理命令判断到来的消息是否与位置相关,如果有关则将对方的位置定位在Google 地图上。
注意:本文的内容是描述一种应用,并非代码讲解(本项目可能以后会结合Android开发总结来讲解)。
三、项目功能展示
由于只有一台测试手机HTC G6,而这个项目是与位置有关的,所以用Android 开发模拟器来最为双方通信的一端。
测试帐号分别是test2@192.168.0.177(由于登录htc g6上的Location-Aware-Instant客户端),test@192.168.0.177(用来登录模拟器上的Location-Aware-Instant客户端)。上面2个帐号格式是Jabber Id(XMPP协议中的帐号,可以参考前排第二篇介绍XMPP的文章),本来是使用test@im.comit.com.cn 在其他桌面客户端解析正常,但手机将im.comit.com.cn的域名解析成一个其他的IP,所以直接使用我本机的IP地址。
本程序的logo:,logo来源自百度百科的XMPP介绍:,我简单的处理了一下。
1. 首先是登录界面(分别使用上面的2个帐号登录两款手机客户端):
HTC g6的登录界面 开发模拟器的登录界面
2. 双方登录并连接到openfire服务器时,会出现双方的在线情况。也就是在服务器上注册了自己的状态为在线。
HTC g6可以看到对方(test) 开发模拟器显示test2在线
3. 操作(目前只加入了定位对方的功能,其实还有发送普通信息、删除联系人等功能,添加联系人)
HTC g6
4. 先来看通过手机模拟器定位htc g6客户端的演示,即点击第三步中手机模拟器(右边)的”获取位置“选项操作。
虽然测试环境在室内,无法获取GPS信号。但HTC g6插入了联通的3G卡所以即时在室内也是可以使用基站定位大概位置。
此时手机模拟器在向G6发送位置感知的请求,G6应该回应自己所在的位置,不到2秒钟后,得到的结果如下图:
我住在棠下,所以G6通过基站大概定位了我的位置,并将位置数据回应给手机模拟器,模拟器将G6所在的位置定位在地图上。
5. 上面演示了通过模拟器定位到G6的位置,现在演示的是G6获取模拟器的位置。但是因为手机模拟器不能获取真实的位置信息,也就无法将自己的信息回复给 G6。解决的方法是在开发工具中输入一个自定义的位置数据。如下图,输入公司在所位置的经纬度(23.143791, 113.347533)。
图中emulator 5554就是我们的模拟器(HT03GNX0404是HTC G6手机)。这样模拟器的位置就定位在公司做位置。
现在尝试通过G6来感知模拟器这个客户端所在的位置,即点击第三步中HTC G6 (左边)的”获取位置“选项操作。结果如下图:
G6客户端程序正在等待手机模拟器的回应,不到2秒钟后:
OK,成功定位到公司所在位置,即G6即可感知到了手机模拟器的位置信息。
到这里手机的位置感知服务基本框架已经出来了。能够即可感知对方的位置,是不是很Cool的体验!
四、项目内容以及结构介绍(代码太长,截图分成上下两部分)
图1 图2
代码结构介绍:以下包名忽略了cn.com.comit.locationaware父包
图1:chat包:与消息发送有关的类
data包:联系人列表,消息等实体类
dialogs包: 交互有关的对话框类
exception包:异常相关的类
map包:与地图和LBS有关的类
图2:service包:封装Smack库和对方提供XMPP服务的封装类。
util包:工具类包
widget.quickantion包:联系人操作(如第三章第3步中的“获取位置”)操作选项控件类
cn.com.comit.locationaware父包:入口以及辅助类
Google APIs 2.2:引用的google android 地图开发包
引用的库:asmack-2010.05.07.jar – Smack的Android优化版API库、trace.jar错误追踪相关包。
五、结束语
1. 传统网络操作方式我们用到 Restful Get获取数据、Post提交数据,但这不是万能的(虽然可以解决大多数的网络应用问题)。通过引入基于PubSub(发布/订阅)的即时通信有时候可以 取得意想不到的体验效果,本项目提出了一个研究方向和思路(虽然离商用还有很长的路要走,可路终究是找到了一条,并且迈出了“万里长征的第一步”)。
2. 最近基于LBS的应用层出不穷,能够将LBS和即时通信进行整合运行,让研究的方向更明确(例如本项目的自动应答功能)。
3. 将即时通信和LBS有机的结合或许可以称作为传说中的“微创新”,毕竟创新不一定是非得创造。