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