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