常逢佳,韋相和,董泉靈
(淮陰師范學(xué)院 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,江蘇 淮安 223300)
Strategy Analytics發(fā)布的最新研究報(bào)告分析指出,2013年全球智能手機(jī)出貨量創(chuàng)新高達(dá)到9.9億臺(tái),比上年增長(zhǎng)41%,Android占據(jù)79%的市場(chǎng)份額,拉開(kāi)了與蘋(píng)果iOS、微軟Windows Phone和其他操作系統(tǒng)的差距。[1]
在國(guó)內(nèi),互聯(lián)網(wǎng)消費(fèi)調(diào)研中心(ZDC.zol.com.cn)2013年10月中國(guó)智能手機(jī)市場(chǎng)不同操作系統(tǒng)產(chǎn)品均價(jià)對(duì)比調(diào)查顯示[2],隨著智能手機(jī)平均售價(jià)差距進(jìn)一步拉大,Android手機(jī)均價(jià)越來(lái)越低,而i-Phone均價(jià)雖然也逐年走低,但與Android手機(jī)的均價(jià)差距卻越來(lái)越大(如表1所示)。
表1 2013年10月中國(guó)智能手機(jī)市場(chǎng)產(chǎn)品均價(jià)對(duì)比
目前,以火狐OS、三星Tizen、旗魚(yú)操作系統(tǒng)為代表的云智能手機(jī)操作系統(tǒng),其寬泛的應(yīng)用程序及成本低廉等優(yōu)點(diǎn),是傳統(tǒng)手機(jī)系統(tǒng)無(wú)法比擬的。云操作系統(tǒng)尚處于萌芽,未來(lái)很有希望獲取大量的市場(chǎng)份額[3]。目前市場(chǎng)上的云手機(jī)無(wú)一例外都采用了Android操作系統(tǒng)。在這種情況之下,Android在全球智能手機(jī)操作系統(tǒng)市場(chǎng)上的份額將持續(xù)走高。
手機(jī)的通信服務(wù)有很多種,其中短信服務(wù)是最基本的。通過(guò)短信服務(wù),用戶(hù)可以收發(fā)個(gè)人和商業(yè)信息。但目前智能手機(jī)中的短信管理方式單一,查詢(xún)功能也不是很健全,主要是根據(jù)聯(lián)系人和收發(fā)短信的時(shí)間先后進(jìn)行顯示及管理。這就帶來(lái)了一些問(wèn)題,隨著短信數(shù)目的增加,用戶(hù)若要查找到目標(biāo)短信,必須瀏覽聯(lián)系人的每一條短信以查找到目標(biāo)短信,查詢(xún)效率低。如果忘記了具體的發(fā)信人,那必須查看每位聯(lián)系人,如此查找到目標(biāo)短信的效率就更低。如文獻(xiàn)[4]所述,順序查找的時(shí)間復(fù)雜度為O(n)。所以,目前的智能手機(jī)需要一個(gè)能夠高效管理短信的第三方軟件來(lái)解決上述問(wèn)題。
綜上所述,本文以Android系統(tǒng)為平臺(tái),設(shè)計(jì)了一套短信高效管理方案來(lái)解決手機(jī)短信管理中的問(wèn)題。
Android的系統(tǒng)短信數(shù)據(jù)庫(kù)在/data/data/com.android.providers.telephony/databases/mmssms.db中,利用SQLite Expert Professional 3查看,發(fā)現(xiàn)其中共有17 張表:addr、android_metadata、attachments、canonical_addresses、drm、part、pdu、pending_msgs、rate、raw、sms、sr_pending、threads、words、words_content、words_segdir、words_segments。[5]
其中本方案涉及的表[6]主要有:
(1)sms表存儲(chǔ)所有短信息數(shù)據(jù)的,主要的字段、字段類(lèi)型及字段說(shuō)明見(jiàn)表2。
表2 sms表字段、字段類(lèi)型及說(shuō)明
(2)threads表存儲(chǔ)著每一個(gè)短信對(duì)話(huà)的線(xiàn)程,主要字段、字段類(lèi)型及字段說(shuō)明見(jiàn)表3。
表3 threads表字段、字段類(lèi)型及說(shuō)明
(3)canonical_addresses表存儲(chǔ)短信會(huì)話(huà)的聯(lián)系人號(hào)碼。主要字段、字段類(lèi)型及字段說(shuō)明見(jiàn)表4。
表4 canonical_addresses字段、字段類(lèi)型及說(shuō)明
sms表的thread_id與threads表的_id相對(duì)應(yīng),threads表的recipient_ids與canonical_addresses表的_id相對(duì)應(yīng)。[6]
Android系統(tǒng)是通過(guò)內(nèi)容提供者(Content-Provider)向應(yīng)用提供訪(fǎng)問(wèn)底層數(shù)據(jù)庫(kù)數(shù)據(jù)的。應(yīng)用程序可以通過(guò)一個(gè)Uri(Uniform Resource Identifier)訪(fǎng)問(wèn)對(duì)應(yīng)的數(shù)據(jù)。短信管理的數(shù)據(jù)存儲(chǔ)主要依賴(lài)三個(gè) ContentProvider:SmsProvider、MmsProvi-der、MmsSmsProvider,以及一個(gè)輔助類(lèi) Telephony。
其中,SmsProvider用于短信相關(guān)數(shù)據(jù)的存取,MmsProvider用于彩信相關(guān)數(shù)據(jù)的存取,MmsSmsProvider則用于短彩信通用數(shù)據(jù)的存取,如會(huì)話(huà)列表、收件箱、草稿(公共屬性)等。[7]
Telephony則提供了一系列Uri、常量字符串、列名數(shù)組、方法等,進(jìn)而方便用戶(hù)使用這些內(nèi)容提供者。
例如:對(duì)短信進(jìn)行分類(lèi)管理時(shí),利用sms表的Uri有
收件箱:URI_SMS_INBOX=Uri.parse("content://sms/inbox").
發(fā) 件 箱 :URI_SMS_OUTBOX=Uri.parse("content://sms/outbox").
草稿箱:URI_SMS_DRAFT=Uri.parse("content://sms/draft").
查詢(xún) conversations信息:URI_SMS_CONVERSATION=Uri.Parse("content://sms/conversations")
查詢(xún)相關(guān)短信聯(lián)系人時(shí),查詢(xún)了threads表的uri:MSG_QUERY_URI=?Uri.parse ("content://mms-sms/conversations??simple=true")。
查 詢(xún) canonical_addresses 表 的 uri:MMS_SMS_ADDRESS_URI?=Uri.parse ("content://mms-sms/canonical-addresses").
對(duì)于數(shù)據(jù)表的訪(fǎng)問(wèn),在Android中采用游標(biāo)方式。如果通過(guò)Activity類(lèi)的managedQuery(uri,projection,selection,selectionArgs,sortOrder) 去直接查詢(xún)管理游標(biāo)(cursor),就是在主線(xiàn)程中進(jìn)行。數(shù)據(jù)量大時(shí),查詢(xún)速度慢,容易出現(xiàn)ANR(Application Not Response應(yīng)用程序無(wú)響應(yīng))異常。因此,在方案設(shè)計(jì)時(shí),采用Android提供的異步框架AsyncQueryHandler去訪(fǎng)問(wèn)ContentProvider所提供的數(shù)據(jù)。
在Android開(kāi)發(fā)中,若要訪(fǎng)問(wèn)系統(tǒng)短信數(shù)據(jù)庫(kù)中的數(shù)據(jù),需要添加訪(fǎng)問(wèn)權(quán)限。該方案設(shè)計(jì)中,需要添加的權(quán)限如下:
讀短信權(quán)限:<uses-permission android:name="android.permission.READ_SMS"/>。
讀聯(lián)系人權(quán)限:<uses-permission android:name="android.permission.READ_CONTACTS"/>。
寫(xiě)短信權(quán)限:<uses-permission android:name="android.permission.WRITE_SMS"/>。
發(fā)送短信權(quán)限:<uses-permission android:name="android.permission.SEND_SMS"/>。
要想提高短信管理系統(tǒng)的開(kāi)發(fā)及運(yùn)行效率可以從以下幾個(gè)方面考慮。
在Android系統(tǒng)中,當(dāng)我們使用ContentProvider操作數(shù)據(jù)庫(kù)時(shí),如果數(shù)據(jù)量很小,是沒(méi)有問(wèn)題的;但如果數(shù)據(jù)量大,應(yīng)用在6秒內(nèi)沒(méi)有對(duì)其進(jìn)行任何處理,UI線(xiàn)程就會(huì)出現(xiàn)ANR異常(Application Not Response應(yīng)用程序無(wú)響應(yīng))。因此,我們通常將比較耗時(shí)的操作放在新線(xiàn)程中執(zhí)行。
如果應(yīng)用需要操作界面,可以使用Handler進(jìn)行處理。只是每次使用ContentProvider時(shí)都要再寫(xiě)一個(gè)Handler,這樣必然降低了程序執(zhí)行效率。API提供了一個(gè)操作數(shù)據(jù)庫(kù)的通用方法——異步查詢(xún)操作幫助類(lèi)AsyncQueryHandler,它也可以處理數(shù)據(jù)的增刪改操作。
AsyncQueryHandler 中提供了 startInsert、start-Delete、startUpdate、startQuery 四項(xiàng)操作,并提供了相對(duì)應(yīng)的onXXXComplete方法,以供操作完數(shù)據(jù)庫(kù)后進(jìn)行其它的操作,這四個(gè)onXXXComplete()方法都是空實(shí)現(xiàn),以便我們只需實(shí)現(xiàn)所關(guān)注的操作。[8]
在本方案中,定義了QueryHandler,繼承了AsyncQueryHandler,提供了 onQueryComplete(int token,Object cookie,Cursor cursor)方法的實(shí)現(xiàn),并通過(guò)Adapter使數(shù)據(jù)發(fā)生改變。
在顯示短信列表時(shí),定義了startQuery()方法,其中使用了AsyncQueryHandler中的mQueryHandler.startQuery() {
Uri uri=Sms.CONVERSATION_URI;
if(thread_ids!=null){
String where=Sms.THREAD_ID+"in"+thread_ids;
mQueryHandler.startQuery (0,null,uri,CONVERSATION_PROJECTION,where,null,"datedesc");}else {mQueryHandler.startQuery(0,null,uri,CONVERSATION_PROJECTION,null,null," date desc");}}方法。
因此,在用戶(hù)短信信息量不斷增多的情況下,避免了ANR異常的出現(xiàn),同時(shí)提高了應(yīng)有程序的運(yùn)行效率。
由表2可知通過(guò)一條短信的日期、時(shí)間、發(fā)送人、接收人等多種屬性可以進(jìn)行查詢(xún)定位。
目前智能手機(jī)基本上都有根據(jù)通信錄查詢(xún)的功能。用戶(hù)在查找前先根據(jù)短信關(guān)聯(lián)的聯(lián)系人,列出與該聯(lián)系人的所有短信,并且所有的短信按照時(shí)間在后排在前的順序顯示。其次,根據(jù)短信內(nèi)容進(jìn)行全文搜索查詢(xún)。這樣用戶(hù)在記不清聯(lián)系人及短信時(shí)間時(shí),可以搜索關(guān)鍵字,對(duì)所有的短信內(nèi)容進(jìn)行定位,由此提高了查找效率。
Android系統(tǒng)自身就有一個(gè)功能健壯的全局搜索模塊,因此,在方案設(shè)計(jì)時(shí),為了提高開(kāi)發(fā)效率,就利用了Android系統(tǒng)自身的搜索模塊功能。具體操作步驟如下:
(1)首先,必須在工程的 res/xml/下創(chuàng)建searchable.xml文檔,具體內(nèi)容如下:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/sms_search"android:hint="@string/sms_search"
android:searchSuggestAuthority="PackageNamePath.MySuggestionProvider"
//給提供查詢(xún)信息服務(wù)的ContentProvider
android:searchSuggestSelection="?" >
//要搜索的關(guān)鍵字
</searchable>
(2)定義提供搜索界面的SearchableActivity
……
if(Intent.ACTION_SEARCH.equals(intent.getAction())){
String query=intent.getStringExtra(SearchManager.QUERY);
//自己的搜索操作
doMySearch(query);
……
對(duì)于上面的界面中必須引用自己定義的查詢(xún)搜索函數(shù) private void doMySearch(String query){
Uri uri=Sms.CONTENT_URI;
String selection=Sms.BODY+"like'%"+query+"%'";
mQueryHandler.startQuery(0,null,uri,SMS_PROJEC
TION,selection,null,Sms.DATE+"desc");
};}
否則,系統(tǒng)會(huì)調(diào)用默認(rèn)的搜索功能。
(3)在清單文件中注冊(cè)
<activity android:name="com.example.SearchableActivity">
<intent-filter>
<action android:name = "android.intent.action.
SEARCH"/>
</intent-filter>
<meta-data android:name="android.app.
searchable" android:resource="@xml/
searchable"/></activity>
點(diǎn)擊搜索功能時(shí),則默認(rèn)調(diào)用系統(tǒng)搜索模塊。若要讓短信管理中的每個(gè)Activity界面中都能使用短信搜索功能,則必須在清單文件中添加<metadata
android:name="android.app.default_searchable"
android:value=".SearchableActivity"/>
否則,跳過(guò)自身定義搜索模塊。
(4)定義提供搜索功能的ContentProvider需要重寫(xiě)其中的
public Cursor query(Uri uri,String[]projection,String selection,
根據(jù)用戶(hù)輸入的信息,到sms表中的BODY字段中查找關(guān)鍵字
Uri uri1=Sms.CONTENT_URI;
String where=Sms.BODY+"like'%"+query+"%'";
并利用游標(biāo)返回查找到的結(jié)果
Cursorcursor= getContext().get-ContentResolver().query(uri1,sms_projection,where,null,Sms.DATE+"desc");
return changeCursor(cursor);}
return null;}
按上述步驟操作即可完成對(duì)短信全文搜索功能的實(shí)現(xiàn)。用戶(hù)對(duì)于一些重要短信可以直接利用關(guān)鍵字查找,大大提高了用戶(hù)查找短信的效率,同時(shí)也提高了短信管理系統(tǒng)的開(kāi)發(fā)效率。
為了方便對(duì)短信進(jìn)行管理,用戶(hù)可以根據(jù)個(gè)人情況建立群組,個(gè)性化的對(duì)短信進(jìn)行分類(lèi)管理[9]。
(1)首先創(chuàng)建 smsmanager.db庫(kù),其中包含groups和thread_groups兩張表。groups表保存群組信息,thread_groups表保存每個(gè)群組中包含的短信息的記錄。具體包含的字段及字段說(shuō)明如下表5、表6所示。
表5 Group表字段、字段類(lèi)型及說(shuō)明
(2)數(shù)據(jù)的訪(fǎng)問(wèn)
在系統(tǒng)中提供了SmsManagerProvider,方便對(duì)群組數(shù)據(jù)進(jìn)行訪(fǎng)問(wèn)。
public Cursor query(Uri uri,String[]projectionIn,String selection,
String[]selectionArgs,String sortOrder)方法中設(shè)置了一個(gè)模式匹配器,根據(jù)傳遞來(lái)的URI進(jìn)行判斷
int code=matcher.match(uri);
switch(code) {
case GROUPS:
qb.setTables("groups");
qb.setProjectionMap(mGroupsProjectionMap);
break;
case THREAD_GROUPS:
qb.setTables("thread_groups");
qb.setProjectionMap (mThread-GroupsProjectionMap);
break;
default:
throw new IllegalArgumentException("沒(méi)有匹配的 uri"+uri);
}
如果出現(xiàn)相同的群組名或者相同的短信thread_id添加到同一群組中時(shí),則提示錯(cuò)誤信息,否則可創(chuàng)建新的群組和添加新的短信到群組中。
在Eclipse下建立工程。應(yīng)用運(yùn)行的主界面如圖1所示。界面主要由會(huì)話(huà),文件夾,群組三個(gè)選項(xiàng)卡組成。[10]
圖1 會(huì)話(huà)選項(xiàng)卡界面
會(huì)話(huà)選項(xiàng)卡中主要包括:(1)短信列表:針對(duì)列表中的短信,可以直接進(jìn)行點(diǎn)擊查看、菜單刪除、編輯等操作;(2)新建信息:點(diǎn)擊按鈕,直接實(shí)現(xiàn)創(chuàng)建短信及發(fā)送等功能。快捷菜單中提供了搜索功能,可以對(duì)短信進(jìn)行全文搜索。
文件夾選項(xiàng)卡主要包括收件箱、發(fā)送箱、已發(fā)送、草稿箱等。用戶(hù)可以在不同文件夾中對(duì)短信進(jìn)行分類(lèi)查找,在相同的類(lèi)別視圖下短信息依據(jù)日期進(jìn)行分隔顯示。界面如圖2、圖3所示。
圖2 文件夾選項(xiàng)卡界面
群組選項(xiàng)卡中初始狀態(tài)是空白的,用戶(hù)點(diǎn)擊快捷鍵彈出新建群組名稱(chēng),可以根據(jù)自身的需要?jiǎng)?chuàng)建群組名。群組創(chuàng)建好后,可以利用快捷鍵向?qū)?yīng)的群組中添加短信。界面如圖4所示。
圖3 收件箱界面
圖4 群組選項(xiàng)卡界面
通過(guò)前面的設(shè)計(jì)分析和實(shí)驗(yàn)結(jié)果,表明使用該方案用戶(hù)能有效地管理Android系統(tǒng)中的短信息??梢钥焖僬业叫枰亩绦牛樵?xún)效率比順序下翻方式提高了很多;同時(shí)還允許用戶(hù)查找內(nèi)容關(guān)鍵詞,這是很多手機(jī)短信管理程序都沒(méi)有的功能;用戶(hù)還可以根據(jù)自己的需要建立個(gè)性化群組,對(duì)短信進(jìn)行分類(lèi)管理。
此外,文中還介紹了Android的系統(tǒng)信息庫(kù),為廣大Android應(yīng)用程序的開(kāi)發(fā)者提供了一定的借鑒與參考。
[1]Gnaix.2013年Android智能手機(jī)全球市場(chǎng)份額達(dá)79%[EB/OL].(2014-02-09)[2014-09-12].http://mobile.chinabyte.com/497/12852997.shtml.
[2]王彥恩.2013年10月中國(guó)智能手機(jī)市場(chǎng)分析報(bào)告[EB/OL].(2013-11-13)[2014-09-12].http://zdc.zol.com.cn/411/4119456_all.html.
[3]網(wǎng)易科技報(bào)道.專(zhuān)家表示云手機(jī)即將威脅Android和iPhone 市場(chǎng)[EB/OL].(2013-9-16)[2014-09-10].http://tech.163.com/13/0916/05/98SCGUUC000915BD.html.
[4]霍靜,毛曉蛟,嚴(yán)善春.基于Android的高效短信查詢(xún)軟件的實(shí)現(xiàn)[J].數(shù)據(jù)庫(kù)與信息管理,2010(10):55-56.
[5]劉安戰(zhàn),賈曉輝.基于Android的私密短信系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].微型機(jī)與應(yīng)用2012,31(17):51-52.
[6]zhangzh332.Android中短信數(shù)據(jù)庫(kù)的簡(jiǎn)單操作[EB/OL].(2011-05-05)[2014-09-10].http://blog.csdn.net/zhangzh332/article/details/6396985.
[7]李剛.瘋狂 android講義[M].北京:電子工業(yè)出版社,2011:400-404.
[8]t12x3456.Android異步查詢(xún)框架AsyncQueryHandler的使用[EB/OL].(2012-08-28)[2014-09-10].http://www.2cto.com/kf/201208/151114.html.
[9]笪林梅.基于Android的手機(jī)通訊錄管理系統(tǒng)的研究與實(shí)現(xiàn)[J].鄭州輕工業(yè)學(xué)院學(xué)報(bào)(自然科學(xué)版),2013(3):61-64.
[10]倪紅軍,錢(qián)昌俊.基于Android平臺(tái)的自發(fā)短信系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].電子技術(shù)應(yīng)用.2012,38(12):126-128.
河北軟件職業(yè)技術(shù)學(xué)院學(xué)報(bào)2015年1期