陸少鵬,周淵平
(四川大學(xué) 電子信息學(xué)院,成都 610065)
基于Android的通訊錄實(shí)時(shí)同步功能①
陸少鵬,周淵平
(四川大學(xué) 電子信息學(xué)院,成都 610065)
隨著Android系統(tǒng)的不斷發(fā)展,Android系統(tǒng)被應(yīng)用在各種設(shè)備上面,包括將Android系統(tǒng)應(yīng)用到有線電話上.因此需要開(kāi)發(fā)一個(gè)通訊錄能夠在搭載了Android系統(tǒng)的有線電話和手機(jī)之間實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)同步.通訊錄的客戶端和服務(wù)端是通過(guò)Socket來(lái)建立連接的,然后采用Handler機(jī)制發(fā)送數(shù)據(jù)和讀取數(shù)據(jù),實(shí)現(xiàn)了通訊錄數(shù)據(jù)的實(shí)時(shí)同步.經(jīng)過(guò)測(cè)試,通訊錄實(shí)現(xiàn)了手機(jī)與有線電話的通話記錄,增加、修改和刪除聯(lián)系人的實(shí)時(shí)同步功能.
Android;通訊錄;實(shí)時(shí)同步;socket;Handler
日常辦公通訊通常使用固定電話,它具有抗干擾能力強(qiáng),通話質(zhì)量好,保密性高的特點(diǎn),最突出的是輻射小[1],因此在室內(nèi)辦公時(shí),用戶更加趨向于使用有線電話.在這種情況下,將手機(jī)和有線電話的通訊錄結(jié)合開(kāi)發(fā),實(shí)現(xiàn)在室外辦公時(shí)能夠?qū)崟r(shí)同步有線電話的未接來(lái)電信息,方便即時(shí)回復(fù)未接來(lái)電,在室內(nèi)辦公時(shí)也能夠?qū)崟r(shí)同步手機(jī)的未接來(lái)電和聯(lián)系人信息,方便電話撥打.
目前的通訊錄同步是為了解決一個(gè)用戶的不同終端設(shè)備的用戶數(shù)據(jù)備份不一致給用戶帶來(lái)不便的問(wèn)題,需要用戶手動(dòng)上傳和下載用戶數(shù)據(jù)才能夠?qū)崿F(xiàn)通訊錄同步[2].現(xiàn)在Android系統(tǒng)的通訊錄同步比較典型的應(yīng)用是小米云同步服務(wù),其包括了通話記錄同步、便簽同步和短信等用戶數(shù)據(jù)的同步[3],但是小米云同步也需要手動(dòng)上傳和下載數(shù)據(jù)進(jìn)行數(shù)據(jù)同步,并不是自動(dòng)進(jìn)行同步的,而且是實(shí)現(xiàn)手機(jī)與手機(jī)之間或者是手機(jī)與平板電腦之間的數(shù)據(jù)同步.
本文所做的通訊錄的實(shí)時(shí)同步和現(xiàn)在的通訊錄同步不同的是,該通訊錄實(shí)現(xiàn)的是實(shí)時(shí)的和自動(dòng)的通訊錄數(shù)據(jù)同步,因此實(shí)時(shí)性比現(xiàn)有的通訊錄同步好,由于是自動(dòng)實(shí)現(xiàn)通訊錄數(shù)據(jù)同步,所以該通訊錄同步操作比現(xiàn)有的通訊錄同步簡(jiǎn)便.而且同步的是手機(jī)和有線電話的通訊錄數(shù)據(jù)庫(kù)數(shù)據(jù)方便室內(nèi)外的辦公.本文所介紹的有線電話是由搭載了Android4.0操作系統(tǒng)的TQ210開(kāi)發(fā)板實(shí)現(xiàn)的,具備了撥號(hào)的功能.
Android系統(tǒng)架構(gòu)采用了分層架構(gòu),從高層到低層依次分為應(yīng)用程序?qū)?、?yīng)用程序框架層、系統(tǒng)運(yùn)行庫(kù)層和Linux核心層[4,5],如圖1.
圖1 Android系統(tǒng)架構(gòu)圖
應(yīng)用程序?qū)铀械某绦蚨际荍AVA語(yǔ)言所編寫(xiě),通過(guò)調(diào)用應(yīng)用程序框架層所提供的 API來(lái)完成的[6]. Android的系統(tǒng)運(yùn)行庫(kù)層分為程序庫(kù)和Android運(yùn)行庫(kù).程序庫(kù)主要包含一些C/C++庫(kù),這些庫(kù)能夠被Android系統(tǒng)的不同組件使用,它們通過(guò)應(yīng)用程序框架層給開(kāi)發(fā)者提供服務(wù).Android運(yùn)行庫(kù)提供Java變成語(yǔ)言核心庫(kù)大部分功能.Android的 Linux核心層是基于Linux2.6內(nèi)核的,是硬件和軟件之間的抽象層.
通訊錄同步系統(tǒng)主要分為客戶端和服務(wù)器端,它們之間通過(guò)Socket建立連接.常用的Socket有兩種:流式Socket和數(shù)據(jù)報(bào)式Socket.流式Socket是一種面向連接的TCP服務(wù)應(yīng)用,數(shù)據(jù)報(bào)式Socket是一種無(wú)連接的UDP服務(wù)應(yīng)用.通訊錄的實(shí)時(shí)同步功能的客戶端和服務(wù)端是采用了流式Socket,其原理框圖如圖2所示.
圖2 系統(tǒng)框圖
由圖2可知,通訊錄的實(shí)時(shí)同步分為兩個(gè)方向,分別為:手機(jī)端實(shí)時(shí)同步有線電話的通訊錄數(shù)據(jù)和有線電話實(shí)時(shí)同步手機(jī)端的通訊錄數(shù)據(jù).
當(dāng)有線電話端的通訊錄數(shù)據(jù)庫(kù)發(fā)生變化時(shí),有線電話端就會(huì)將發(fā)生變化的數(shù)據(jù)轉(zhuǎn)換成輸出流,并將該輸出流發(fā)送給服務(wù)器端,服務(wù)器端讀取到該輸出流數(shù)據(jù)后將它轉(zhuǎn)換為輸出流供手機(jī)端讀取該同步數(shù)據(jù),該過(guò)程實(shí)現(xiàn)了手機(jī)端實(shí)時(shí)同步有線電話端的通訊錄數(shù)據(jù),如圖2中灰色線過(guò)程.
有線電話端實(shí)時(shí)同步手機(jī)端通訊錄數(shù)據(jù)的過(guò)程就是紅色線過(guò)程,即當(dāng)手機(jī)端的通訊錄數(shù)據(jù)庫(kù)發(fā)生變化時(shí),手機(jī)端就將變化的數(shù)據(jù)轉(zhuǎn)換成輸出流并將該輸出流發(fā)生給服務(wù)器端,服務(wù)器端讀取到該數(shù)據(jù)后再將該數(shù)據(jù)轉(zhuǎn)換為輸出流供有線電話端讀取同步數(shù)據(jù),最終實(shí)現(xiàn)有線電話通訊錄實(shí)時(shí)同步手機(jī)端的通訊錄數(shù)據(jù).
通訊錄的的實(shí)時(shí)同步功能主要包括四個(gè)部分:通話記錄、添加聯(lián)系人、刪除聯(lián)系人和修改聯(lián)系人的實(shí)時(shí)同步.客戶端的程序流程圖如圖3.
圖3 客戶端程序流程圖
客戶端的實(shí)現(xiàn)主要分為兩個(gè)部分,一個(gè)部分是判斷客戶端是否連接網(wǎng)絡(luò),連接網(wǎng)絡(luò)就將同步數(shù)據(jù)發(fā)送到服務(wù)器端,未連接網(wǎng)絡(luò)就將同步數(shù)據(jù)存到SQLite數(shù)據(jù)庫(kù)中.另一部分就是要實(shí)時(shí)監(jiān)聽(tīng)通訊錄數(shù)據(jù)庫(kù)的數(shù)據(jù)變化,有數(shù)據(jù)變化時(shí)就發(fā)送數(shù)據(jù)到服務(wù)端,沒(méi)有數(shù)據(jù)變化時(shí)就處于不斷監(jiān)聽(tīng)狀態(tài).
客戶端為了能夠?qū)⑼綌?shù)據(jù)發(fā)送到服務(wù)器端需要處于連接網(wǎng)絡(luò)的狀態(tài),所以,在發(fā)送數(shù)據(jù)之前必須先檢查客戶端是否連接網(wǎng)絡(luò).客戶端用getSystemService (Context.CONNECTIVITY_SERVICE)方法來(lái)獲取ConnectivityManger類(lèi)的對(duì)象,然后再通過(guò)該對(duì)象的getAllNetworkInfo()方法來(lái)獲取到客戶端的所有網(wǎng)絡(luò)連接情況的對(duì)象,最后再使用該對(duì)象的getState()方法來(lái)判斷客戶端網(wǎng)絡(luò)連接情況并且與 NetworkInfo. state.CONNECTED對(duì)比判斷是否相等就可以判斷出客戶端是否處于連接網(wǎng)絡(luò)的狀態(tài).如果上面的判斷結(jié)果是客戶端未連接網(wǎng)絡(luò),則將同步數(shù)據(jù)存儲(chǔ)在SQLite數(shù) 據(jù) 庫(kù) 中.SQLite數(shù) 據(jù) 庫(kù) 是 通 過(guò) 繼 承SQLiteOpenHelper類(lèi)來(lái)實(shí)現(xiàn)的.該數(shù)據(jù)庫(kù)里面創(chuàng)建了兩個(gè)表,分別為聯(lián)系人表和通話記錄表,分別用于存儲(chǔ)聯(lián)系人同步數(shù)據(jù)和通話記錄同步數(shù)據(jù).如果客戶端判斷為處于連接網(wǎng)絡(luò)狀態(tài),則先將SQLite數(shù)據(jù)庫(kù)中存儲(chǔ)的所有同步數(shù)據(jù)和客戶端數(shù)據(jù)庫(kù)剛更新的同步數(shù)據(jù)發(fā)送到服務(wù)器端.每當(dāng)將SQLite數(shù)據(jù)庫(kù)中的同步數(shù)據(jù)發(fā)送出去之后,就會(huì)調(diào)用SQLite數(shù)據(jù)庫(kù)的delete()方法將舊的數(shù)據(jù)刪除掉,方便之后的操作.
要實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)同步首先得通過(guò)使用ContentObserver內(nèi)容觀察者監(jiān)聽(tīng)通話記錄數(shù)據(jù)庫(kù)數(shù)據(jù)和聯(lián)系人數(shù)據(jù)庫(kù)的變化.假設(shè)手機(jī)有來(lái)電或則去電致使手機(jī)端的通話記錄數(shù)據(jù)庫(kù)數(shù)據(jù)發(fā)生變化或者手機(jī)端有對(duì)聯(lián)系人數(shù)據(jù)庫(kù)進(jìn)行增加、刪除或修改的操作致使聯(lián)系人數(shù)據(jù)庫(kù)發(fā)生變化,就會(huì)觸發(fā)ContentObserver里面的onChange()方法,然后就可以在這個(gè)方法里面去獲取新的數(shù)據(jù)并且通過(guò)out.println()把該條數(shù)據(jù)發(fā)送給服務(wù)器端.同時(shí),有線電話端就可以通過(guò)重寫(xiě)Handler機(jī)制的handleMessage()方法來(lái)從服務(wù)器端獲取到同步數(shù)據(jù).有線電話端獲取到同步數(shù)據(jù)之后,讀取同步數(shù)據(jù)的標(biāo)志位flag來(lái)判斷該條數(shù)據(jù)是屬于通話記錄類(lèi)型的還是聯(lián)系人數(shù)據(jù)類(lèi)型的.如果該條數(shù)據(jù)屬于通話記錄數(shù)據(jù)類(lèi)型的,就需要將同步數(shù)據(jù)與本地通話記錄數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行對(duì)比,如果該條同步數(shù)據(jù)是本地?cái)?shù)據(jù)則不進(jìn)行任何操作,如果同步數(shù)據(jù)非本地?cái)?shù)據(jù)就需要通過(guò)Util.AddNumToCallLog()把同步數(shù)據(jù)插入到通話記錄數(shù)據(jù)庫(kù)中.如果這條數(shù)據(jù)是聯(lián)系人數(shù)據(jù)類(lèi)型的,也需要將該條同步數(shù)據(jù)與本地聯(lián)系人數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行對(duì)比,如果該條數(shù)據(jù)屬于本地?cái)?shù)據(jù)庫(kù)則不進(jìn)行任何操作,否則通過(guò) Util.AddContact()、Util.ChangeCotact()和Util.DeleteContact()分別對(duì)聯(lián)系人數(shù)據(jù)庫(kù)進(jìn)行添加、修改和刪除操作.通話記錄數(shù)據(jù)庫(kù)或則聯(lián)系人數(shù)據(jù)庫(kù)完成數(shù)據(jù)更新之后,就會(huì)觸發(fā)加載器Loader的回調(diào)機(jī)制onLoadFinished()方法通知最終的運(yùn)行結(jié)果,之后就會(huì)調(diào)用適配器的notifyDataSetChanged()方法,即當(dāng)適配器的內(nèi)容發(fā)生變化時(shí)通過(guò)這個(gè)方法強(qiáng)制調(diào)用getView來(lái)刷新每個(gè)item的內(nèi)容,可以實(shí)現(xiàn)動(dòng)態(tài)刷新列表從而動(dòng)態(tài)更新UI界面.通過(guò)以上步驟有線電話端就可以實(shí)現(xiàn)實(shí)時(shí)同步手機(jī)端的數(shù)據(jù)了,反之同樣可以實(shí)現(xiàn)手機(jī)端實(shí)時(shí)同步有線電話端的數(shù)據(jù).
客戶端的Android程序是在Eclipse中建立的,在工程中建立了通話記錄功能包、聯(lián)系人功能包和內(nèi)容觀察者功能包等,這些功能包里面的Java代碼分別實(shí)現(xiàn)了通訊錄的聯(lián)系人功能和顯示通話記錄功能等,其Android工程目錄如圖4所示.
圖4 客戶端工程目錄
服務(wù)器端是采用ServerSocket創(chuàng)建的TCP服務(wù)端.服務(wù)器端程序流程圖如圖5所示.
圖5 服務(wù)器端程序流程圖
服務(wù)器端為了實(shí)現(xiàn)與客戶端的連接,首先得使用ServerSocket()構(gòu)造器創(chuàng)建一個(gè)服務(wù)器端的對(duì)象,然后在while(true)代碼塊里面使用server類(lèi)的accept()方法不斷地監(jiān)聽(tīng)等待來(lái)自客戶端的連接請(qǐng)求.由于,服務(wù)端得實(shí)現(xiàn)來(lái)自多個(gè)客戶端的連接請(qǐng)求,所以,得使用Executors類(lèi)下面的newCachedThreadPool()方法來(lái)存儲(chǔ)多個(gè)客戶端的連接請(qǐng)求并且得使用Java的多線程技術(shù)來(lái)分別處理來(lái)自不同客戶端的連接請(qǐng)求.當(dāng)服務(wù)器端監(jiān)聽(tīng)到了來(lái)自客戶端的連接請(qǐng)求之后,就會(huì)和客戶端建立連接并且將該客戶端添加到連接池中.與客戶端建立連接之后,為了能夠獲取到客戶端的同步數(shù)據(jù),需要在服務(wù)器端使用Socket對(duì)象的getInputStream()方法來(lái)獲取輸入流對(duì)象,并且使用輸入流對(duì)象的readLine()方法來(lái)讀取來(lái)自客戶端輸出的同步數(shù)據(jù).實(shí)現(xiàn)了服務(wù)器端的接收數(shù)據(jù)功能之后,就需要對(duì)所接收到的數(shù)據(jù)進(jìn)行合法性判斷.如果接收到的同步數(shù)據(jù)是不合法的就將該丟棄該同步數(shù)據(jù)并且不做任何操作,如果該同步數(shù)據(jù)合法就需要將該合法的同步數(shù)據(jù)發(fā)送給客戶端.因此,服務(wù)器端為了能夠?qū)⑼綌?shù)據(jù)發(fā)送給客戶端,服務(wù)器端需要使用 Socket對(duì)象的getOutputStream()方法獲取輸出流對(duì)象,然后使用輸出流對(duì)象的println()將同步數(shù)據(jù)發(fā)送出去.實(shí)現(xiàn)上述功能之后,客戶端就可以從服務(wù)器端讀取到同步數(shù)據(jù)了.
服務(wù)器端功能實(shí)現(xiàn)是在集成開(kāi)發(fā)環(huán)境Eclipse中使用Java編程語(yǔ)言編寫(xiě)的,其工程目錄如圖6所示.
圖6 服務(wù)器端工程目錄
測(cè)試系統(tǒng)能否正常工作分為以下幾步[7,8]:
① 將TQ210開(kāi)發(fā)板和電話模塊連接起來(lái),組成系統(tǒng)測(cè)試所需要的搭載了Android系統(tǒng)的有線電話,并打開(kāi)開(kāi)發(fā)板電源.
② 打開(kāi)Eclipse集成開(kāi)發(fā)環(huán)境,首先啟動(dòng)服務(wù)器端的程序,使服務(wù)器處于工作狀態(tài).然后,在手機(jī)端和有線電話端安裝通訊錄的apk,并且使手機(jī)端和有線電話端的通訊錄都處于工作狀態(tài).
③ 測(cè)試聯(lián)系人模塊的實(shí)時(shí)同步功能,首先,進(jìn)入手機(jī)端和有線電話端通訊錄的聯(lián)系人操作界面.然后,在手機(jī)端新增一個(gè)聯(lián)系人保存該聯(lián)系人之后,此時(shí)可以看到手機(jī)端和有線電話端同時(shí)新增了同一個(gè)聯(lián)系人.如圖7所示.
圖7 添加聯(lián)系人同步結(jié)果
④ 在手機(jī)端通訊錄編輯剛才新添加的聯(lián)系人,把該聯(lián)系人的電話號(hào)碼進(jìn)行修改,保存之后可以觀察到手機(jī)端的聯(lián)系人和有線電話端的聯(lián)系人的電話號(hào)碼同時(shí)發(fā)生了改變.如圖8所示.
圖8 編輯聯(lián)系人同步結(jié)果
圖9 刪除聯(lián)系人同步結(jié)果
⑥ 手機(jī)和有線電話同時(shí)進(jìn)入通訊錄的通話記錄界面,然后向手機(jī)撥打電話,通話結(jié)束后可以看到手機(jī)和有線電話的通話記錄同時(shí)更新了同一條信息,可以通過(guò)觀察通話記錄上面的時(shí)間確定通話記錄的實(shí)時(shí)同步.如圖10所示.
圖10 通話記錄同步結(jié)果
經(jīng)過(guò)上面的測(cè)試結(jié)果可以知道,該通訊錄實(shí)現(xiàn)了通話記錄和增加、修改和刪除聯(lián)系人的實(shí)時(shí)同步功能.
經(jīng)過(guò)上面的測(cè)試,可以得出結(jié)論:該通訊錄具有在通話記錄和添加、刪除、修改聯(lián)系人的實(shí)時(shí)同步功能.事實(shí)上,可以把這個(gè)實(shí)時(shí)同步功能應(yīng)用到辦公人員的手機(jī)和辦公電話上.當(dāng)辦公人員在外工作時(shí),如果辦公電話有未接來(lái)電時(shí),辦公人員可以即時(shí)知道這條來(lái)電信息并及時(shí)回復(fù).也可以將該通訊錄應(yīng)用到具有多部手機(jī)的用戶的手機(jī)上,只要每部手機(jī)都安裝了該通訊錄,就可以實(shí)現(xiàn)多部手機(jī)的通訊錄數(shù)據(jù)的實(shí)時(shí)同步,這樣可以免去用戶在多部手機(jī)的同一個(gè)聯(lián)系人進(jìn)行相同的添加、刪除和修改的操作.再則,隨著4G和5G的發(fā)展,手機(jī)在室內(nèi)的通話質(zhì)量越來(lái)越差,在室內(nèi)使用有線電話通話會(huì)比手機(jī)好,所以實(shí)現(xiàn)這個(gè)實(shí)時(shí)同步功能可以方便用戶在有線電話上撥打手機(jī)端的聯(lián)系人,免去查詢電話號(hào)碼的麻煩.因此,這個(gè)通訊錄的實(shí)時(shí)同步功能具有很好應(yīng)用前景.
1薛瑩,徐慨,黃麟舒.來(lái)電顯示電路的設(shè)計(jì).艦船電子工程, 2008,28(9):44–47.
2馬慶鐘,姜弢.基于SyncML的CooTalk通訊錄同步設(shè)計(jì)與實(shí)現(xiàn)[碩士學(xué)位論文].哈爾濱:哈爾濱工程大學(xué),2013.
3李輝,楊若瑜.基于安卓手機(jī)的信息云同步系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[碩士學(xué)位論文].南京:南京大學(xué),2014.
4熊積健,王琪.基于S5PV210平板電腦的設(shè)計(jì).江西通信科技,2012,(1):12–15.
5姚昱旻,劉衛(wèi)國(guó).Android的架構(gòu)與應(yīng)用開(kāi)發(fā)研究.計(jì)算機(jī)系統(tǒng)應(yīng)用,2008,17(11):110–112.
6凡威,周淵平.基于Android平臺(tái)的無(wú)線視頻監(jiān)控.計(jì)算機(jī)系統(tǒng)應(yīng)用,2015,24(1):195–198.
7杜江,周淵平.基于Android的電話撥號(hào)功能.計(jì)算機(jī)系統(tǒng)應(yīng)用,2014,23(12):245–248.
8陳成偉,周淵平.基于Android的有線電話CID功能.計(jì)算機(jī)系統(tǒng)應(yīng)用,2016,25(1):85–89.
Real-Time Synchronization Function for Contact Based onAndroid
LU Shao-Peng,ZHOU Yuan-Ping
(College of Electronic Information,Sichuan University,Chengdu 610065,China)
With the continuous development of Android system,the Android system has been used in a variety of devices,including applying to wire telephones.Therefore,we need to develop a contact which has the real-time synchronization function between wire telephone and mobile phone equipped with Android system.The contact establishes connection between client and server by using Socket,and using Handler mechanism to send data and read data,as a result,it realizes the function of the real-time synchronization for contact data.The test shows the contact achieves the goal of the real-time synchronization function of calling records,adding,modifying and deleting contacts between mobile phone and wire telephone.
Android;contact;real-time synchronization;socket;Handler
2016-08-03;收到修改稿時(shí)間:2016-09-18
10.15888/j.cnki.csa.005725