一、回顧 在分享這個(gè)項(xiàng)目之前先來(lái)回顧以前的三篇文章:
《基于即時(shí)通信和LBS技術(shù)的位置感知服務(wù)(一):提出問(wèn)題及解決方案》(外網(wǎng)地址)
在第一篇文章中我們提出了要讓A與B在不同地方能即刻獲取對(duì)方準(zhǔn)確位置的需求。之后討論了解決這一問(wèn)題做出的方案選擇,即放棄使用輪詢(xún)(Pooling) 的方式在不同客戶端進(jìn)行數(shù)據(jù)的更新,理由是因?yàn)锽不知道A何時(shí)需要自己的位置信息,所以B只能一直post自己的位置數(shù)據(jù)給服務(wù)器,而A要定時(shí)通過(guò) RESTful Web請(qǐng)求去服務(wù)器獲取B的信息。
最后確定采用基于XMPP協(xié)議的PubSub(Publish/Subscribe,發(fā)布/訂閱)方式進(jìn)行異步消息實(shí)時(shí)傳遞。
《基于即時(shí)通信和LBS技術(shù)的位置感知服務(wù)(二):XMPP協(xié)議總結(jié)以及開(kāi)源解決方案》(外網(wǎng)地址)
第二篇文章主要是對(duì)XMPP協(xié)議進(jìn)行總結(jié),以及為什么要采用XMPP,最后介紹了XMPP協(xié)議的Java開(kāi)源解決方案:Openfire+Smack+Spark。
《基于即時(shí)通信和LBS技術(shù)的位置感知服務(wù)(三):搭建Openfire服務(wù)器+測(cè)試2款I(lǐng)M客戶端》(外網(wǎng)地址)
第三篇文章詳細(xì)講解了基于XMPP協(xié)議的openfire服務(wù)架設(shè),以及使用2款異構(gòu)的基于XMPP協(xié)議的桌面客戶端測(cè)試即時(shí)消息傳遞。
特別提示:為了更好的了解本項(xiàng)目要解決的問(wèn)題,強(qiáng)烈建議去看看前面的三篇連載。
二、Location-Aware-Instant項(xiàng)目概括
Location-Aware-Instant是一個(gè)運(yùn)行在Android OS 上具有位置即時(shí)感知功能的Android應(yīng)用程序客戶端。與之前第三篇文章里介紹了2款桌面程序一樣,遵循開(kāi)放標(biāo)準(zhǔn)的XMPP協(xié)議。
開(kāi)發(fā)過(guò)程查找和參考了不少外文資料和相關(guān)項(xiàng)目,利用周末和晚上的時(shí)間、現(xiàn)在已經(jīng)終于完成了90%。
本程序的架構(gòu)和技術(shù)基礎(chǔ):
1. Android OS 應(yīng)用開(kāi)發(fā)技術(shù):包括地圖應(yīng)用開(kāi)發(fā)。
2. Openfire服務(wù)器:基于XMPP協(xié)議的開(kāi)源Java服務(wù)器端程序。
3. Smack 開(kāi)發(fā)庫(kù):對(duì)XMPP協(xié)議進(jìn)行了封裝的客戶端實(shí)現(xiàn)的Java開(kāi)發(fā)包。本項(xiàng)目采用的是ASmack Library(適合與Android OS 的Smack優(yōu)化版)。
本項(xiàng)目的實(shí)現(xiàn)原理。共分三個(gè)層次:
1. 首先使用Openfire作為服務(wù)器,通過(guò)使用ASmack庫(kù)開(kāi)發(fā)出帶有聯(lián)系人列表的即時(shí)消息傳遞程序;
2. 然后客戶端發(fā)送和接收消息之間植入自己的攔截預(yù)處理邏輯,并通過(guò)定制特殊的命令,實(shí)現(xiàn)消息的自動(dòng)應(yīng)答功能;
3. 最后一層在接收消息時(shí),根據(jù)預(yù)處理命令判斷是否對(duì)方的意圖為定位請(qǐng)求,如果是則調(diào)用位置定位相關(guān)方法獲取本地位置并自動(dòng)恢復(fù)給發(fā)送請(qǐng)求一方,請(qǐng)求方根據(jù)預(yù)處理命令判斷到來(lái)的消息是否與位置相關(guān),如果有關(guān)則將對(duì)方的位置定位在Google 地圖上。
注意:本文的內(nèi)容是描述一種應(yīng)用,并非代碼講解(本項(xiàng)目可能以后會(huì)結(jié)合Android開(kāi)發(fā)總結(jié)來(lái)講解)。
三、項(xiàng)目功能展示
由于只有一臺(tái)測(cè)試手機(jī)HTC G6,而這個(gè)項(xiàng)目是與位置有關(guān)的,所以用Android 開(kāi)發(fā)模擬器來(lái)最為雙方通信的一端。
測(cè)試帳號(hào)分別是test2@192.168.0.177(由于登錄htc g6上的Location-Aware-Instant客戶端),test@192.168.0.177(用來(lái)登錄模擬器上的Location-Aware-Instant客戶端)。上面2個(gè)帳號(hào)格式是Jabber Id(XMPP協(xié)議中的帳號(hào),可以參考前排第二篇介紹XMPP的文章),本來(lái)是使用test@im.comit.com.cn 在其他桌面客戶端解析正常,但手機(jī)將im.comit.com.cn的域名解析成一個(gè)其他的IP,所以直接使用我本機(jī)的IP地址。
本程序的logo:
,logo來(lái)源自百度百科的XMPP介紹:
,我簡(jiǎn)單的處理了一下。
1. 首先是登錄界面(分別使用上面的2個(gè)帳號(hào)登錄兩款手機(jī)客戶端):
HTC g6的登錄界面
開(kāi)發(fā)模擬器的登錄界面
2. 雙方登錄并連接到openfire服務(wù)器時(shí),會(huì)出現(xiàn)雙方的在線情況。也就是在服務(wù)器上注冊(cè)了自己的狀態(tài)為在線。
HTC g6可以看到對(duì)方(test)
開(kāi)發(fā)模擬器顯示test2在線
3. 操作(目前只加入了定位對(duì)方的功能,其實(shí)還有發(fā)送普通信息、刪除聯(lián)系人等功能,添加聯(lián)系人)
HTC g6 
4. 先來(lái)看通過(guò)手機(jī)模擬器定位htc g6客戶端的演示,即點(diǎn)擊第三步中手機(jī)模擬器(右邊)的”獲取位置“選項(xiàng)操作。
雖然測(cè)試環(huán)境在室內(nèi),無(wú)法獲取GPS信號(hào)。但HTC g6插入了聯(lián)通的3G卡所以即時(shí)在室內(nèi)也是可以使用基站定位大概位置。

此時(shí)手機(jī)模擬器在向G6發(fā)送位置感知的請(qǐng)求,G6應(yīng)該回應(yīng)自己所在的位置,不到2秒鐘后,得到的結(jié)果如下圖:

我住在棠下,所以G6通過(guò)基站大概定位了我的位置,并將位置數(shù)據(jù)回應(yīng)給手機(jī)模擬器,模擬器將G6所在的位置定位在地圖上。
5. 上面演示了通過(guò)模擬器定位到G6的位置,現(xiàn)在演示的是G6獲取模擬器的位置。但是因?yàn)槭謾C(jī)模擬器不能獲取真實(shí)的位置信息,也就無(wú)法將自己的信息回復(fù)給 G6。解決的方法是在開(kāi)發(fā)工具中輸入一個(gè)自定義的位置數(shù)據(jù)。如下圖,輸入公司在所位置的經(jīng)緯度(23.143791, 113.347533)。

圖中emulator 5554就是我們的模擬器(HT03GNX0404是HTC G6手機(jī))。這樣模擬器的位置就定位在公司做位置。
現(xiàn)在嘗試通過(guò)G6來(lái)感知模擬器這個(gè)客戶端所在的位置,即點(diǎn)擊第三步中HTC G6 (左邊)的”獲取位置“選項(xiàng)操作。結(jié)果如下圖:

G6客戶端程序正在等待手機(jī)模擬器的回應(yīng),不到2秒鐘后:

OK,成功定位到公司所在位置,即G6即可感知到了手機(jī)模擬器的位置信息。
到這里手機(jī)的位置感知服務(wù)基本框架已經(jīng)出來(lái)了。能夠即可感知對(duì)方的位置,是不是很Cool的體驗(yàn)!
四、項(xiàng)目?jī)?nèi)容以及結(jié)構(gòu)介紹(代碼太長(zhǎng),截圖分成上下兩部分)
圖1
圖2
代碼結(jié)構(gòu)介紹:以下包名忽略了cn.com.comit.locationaware父包
圖1:chat包:與消息發(fā)送有關(guān)的類(lèi)
data包:聯(lián)系人列表,消息等實(shí)體類(lèi)
dialogs包: 交互有關(guān)的對(duì)話框類(lèi)
exception包:異常相關(guān)的類(lèi)
map包:與地圖和LBS有關(guān)的類(lèi)
圖2:service包:封裝Smack庫(kù)和對(duì)方提供XMPP服務(wù)的封裝類(lèi)。
util包:工具類(lèi)包
widget.quickantion包:聯(lián)系人操作(如第三章第3步中的“獲取位置”)操作選項(xiàng)控件類(lèi)
cn.com.comit.locationaware父包:入口以及輔助類(lèi)
Google APIs 2.2:引用的google android 地圖開(kāi)發(fā)包
引用的庫(kù):asmack-2010.05.07.jar – Smack的Android優(yōu)化版API庫(kù)、trace.jar錯(cuò)誤追蹤相關(guān)包。
五、結(jié)束語(yǔ)
1. 傳統(tǒng)網(wǎng)絡(luò)操作方式我們用到 Restful Get獲取數(shù)據(jù)、Post提交數(shù)據(jù),但這不是萬(wàn)能的(雖然可以解決大多數(shù)的網(wǎng)絡(luò)應(yīng)用問(wèn)題)。通過(guò)引入基于PubSub(發(fā)布/訂閱)的即時(shí)通信有時(shí)候可以 取得意想不到的體驗(yàn)效果,本項(xiàng)目提出了一個(gè)研究方向和思路(雖然離商用還有很長(zhǎng)的路要走,可路終究是找到了一條,并且邁出了“萬(wàn)里長(zhǎng)征的第一步”)。
2. 最近基于LBS的應(yīng)用層出不窮,能夠?qū)BS和即時(shí)通信進(jìn)行整合運(yùn)行,讓研究的方向更明確(例如本項(xiàng)目的自動(dòng)應(yīng)答功能)。
3. 將即時(shí)通信和LBS有機(jī)的結(jié)合或許可以稱(chēng)作為傳說(shuō)中的“微創(chuàng)新”,畢竟創(chuàng)新不一定是非得創(chuàng)造。