2-4 通話+信息功能技術(shù)_第1頁
2-4 通話+信息功能技術(shù)_第2頁
2-4 通話+信息功能技術(shù)_第3頁
2-4 通話+信息功能技術(shù)_第4頁
2-4 通話+信息功能技術(shù)_第5頁
已閱讀5頁,還剩13頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

/目錄1 根本要求 12 打電話流程 12.1 1OutgoingCallBroadcaster.java 22.2 2OutgoingCallReceiver.java 22.3 3InCallScreen.java——負責(zé)通話的那一個界面 22.3.1 3.1)onCreate(第一次) 22.3.2 3.2)onNewIntent(非第一次)。 32.3.3 3.3)onResume 32.4 4Profiler.java——該類對通話各個時間點進行記錄。 32.5 5PhoneUtils.java——負責(zé)Phone對象的生成 32.5.1 5.1)placeCall(Phonephone,Stringnumber,UricontactRef) 42.5.2 5.2)placeCallVia(Contextcontext,Phonephone,Stringnumber,UricontactRef,UrigatewayUri) 42.6 6PhoneApp.java——負責(zé)Phone對象頂層應(yīng)用的生成 42.7 7CallNotifier.java——監(jiān)聽Phone狀態(tài)改變和telephony層事件,觸發(fā)UI行為 43 電話局部 53.1 判斷電話接通狀態(tài) 63.2 刪除通話記錄 64 短信局部 84.1 發(fā)送短信 84.2 發(fā)送彩信 84.3 刪除短信 84.4 監(jiān)聽短信收發(fā) 104.4.1 利用播送 104.4.2 利用數(shù)據(jù)庫 114.5 收到短信不頂欄通知 124.6 獲取短信內(nèi)容 12根本要求要求能夠向指定的號碼發(fā)起呼叫;能夠監(jiān)視呼入事件,并得到呼入的號碼;嘗試對呼入事件進行處理(顯示給用戶或者直接拒絕);通話記錄的獲取以及刪除;上述技術(shù)點都涉及到應(yīng)用程序平安授權(quán)問題,研究Android在保證應(yīng)用程序平安上采用的方法。打電話流程1OutgoingCallBroadcaster.java點擊撥號盤撥打按鈕后,進入通話的Phone包。此時首先進入的函數(shù)OutgoingCallBroadcaster.java,該類是一個Activity。由activity的生命周期可知,第一次進入時應(yīng)調(diào)用onCreate()函數(shù)。(在該類中也只實現(xiàn)了這個函數(shù)。)解析一下這個函數(shù):1.1)首先獲取Intent對象,獲取撥出的號碼。1.2)接著判斷號碼是否為緊急號碼,如果是緊急號碼,將callNow變量賦值為true,啟動InCallScreen,并發(fā)送播送。而在receiver里面判斷callNow為ture就直接finish,而不再重復(fù)啟動InCallScreen;如果不是緊急號碼,將callNow變量賦值為false,發(fā)送播送“Intent.ACTION_NEW_OUTGOING_CALL〞。2OutgoingCallReceiver.java播送發(fā)送后OutgoingCallReceiver將會收到該息。該類是一個內(nèi)部類,在類OutgoingCallBroadcaster里面,作用是接收OutgoingCallBroadcaster發(fā)送的播送,判斷是否已經(jīng)啟動InCallScreen。沒有啟動的話就進行一些初始化,如:對OTA進行初始化。接收到播送之后,從Intent里面取出電話號碼及其URi。然后,設(shè)置Intent為ACTION_CALL,并帶上號碼和uri。啟動InCallScreen。關(guān)閉該Activity。OTA:Over-the-AirTechnology空中下載技術(shù),是通過移動通信(GSM或CDMA)的空中接口對SIM卡數(shù)據(jù)及應(yīng)用進行遠程管理的技術(shù)??罩薪涌诳梢圆捎?、CDMA1X及短消息技術(shù)。OTA技術(shù)的應(yīng)用,使得移動通信不僅可以提供語音和數(shù)據(jù)效勞,而且還能提供新業(yè)務(wù)下載。GSM:GlobalSystemforMobileCommunications,中文為全球移動通訊系統(tǒng),俗稱"全球通"。CDMA:CodeDivisionMultipleAccess,又稱碼分多址,是在無線通訊上使用的技術(shù),CDMA允許所有的使用者同時使用全部頻帶(1.2288Mhz),并且把其他使用者發(fā)出的訊號視為雜訊,完全不必考慮到訊號碰撞(collision)的問題。CDMA的優(yōu)點包括:CDMA中所提供的語音編碼技術(shù),其通話品質(zhì)比目前的GSM好,而且可以把用戶對話時周圍環(huán)境的噪音降低,使通話更為清晰。3InCallScreen.java——負責(zé)通話的那一個界面該類extends了Acitivity,并且implements了OnClickListener,OnTouchListener和OnQueryCompleteListener。該類主要是負責(zé)通話的那一個界面,并且還負責(zé)菜單項各種按鍵事件和觸摸時間的處理。同時本類還復(fù)寫的finish()方法,所以一般不會被finish掉,調(diào)用這個方法時它又把自己放回棧中。InCallScreen可以接收這個Intent并啟動。3.1)onCreate(第一次)3.1.1)callScreenOnCreate獲得通話界面被創(chuàng)立的時間。3.1.2)PhoneApp喚醒后臺的效勞程序。3.1.3)判斷當(dāng)前的通話狀態(tài)(IDLE=沒有通話行為,RINGING=正在通話或呼叫等待,OFFHOOK=Thephoneisoffhook.Atleastonecallexiststhatisdialing,activeorholdingandnocallsareringingorwaiting.),如果正在通話,不會出現(xiàn)鍵盤鎖。接著設(shè)置mPhoneandmForegroundCall/mBackgroundCall/mRingingCall。3.1.4)getBluetoothHandsfree設(shè)置藍牙耳機,如果存在藍牙耳機,則安裝該設(shè)備。3.1.5)initInCallScreen加載各種view組建。3.1.6)對通話的各種狀態(tài)進行播送。(registerForPreciseCallStateChanged,registerForDisconnect,registerForMmiInitiateregisterForMmiComplete,registerForCallWaiting,registerForSuppServiceFailed,registerForCdmaOtaStatusChange)3.1.7)internalResolveIntent判斷是否使用了OTA技術(shù),通過該判斷設(shè)置通話界面的樣式。3.1.8)callScreenCreated記錄通話界面創(chuàng)立完成后的時間3.2)onNewIntent(非第一次)。我們重新啟動一個Intent時調(diào)用該函數(shù)。由于我們圍繞唯一的一個InCallScreen實例來完成通過的這個過程,那么除了第一次被創(chuàng)立的InCallScreen,只要有來電或者去電,該程序就會發(fā)生。如果InCallScreen已經(jīng)在前臺,該程序也會發(fā)生。3.2.1)setIntent保存該Intent,以至于將來我們可以獲得該intent。3.2.2)internalResolveIntent3.3)onResume進行一些初始化操作,如:獲取一個PhoneApp對象,解開KeyguardNotification的statusBar給Disable。還內(nèi)置了一個Handler可以回調(diào)處理一些事件,比方:PHONE_STATE_CHANGED,PHONE_DISCONNECT,EVENT_HEADSET_PLUG_STATE_CHANGED。同時有一個獨立的BroadcastReceiver處理ACTION_HEADSET_PLUG,比方插入耳機等。3.3.1)首先對鎖屏情況下的來電除了處理。3.3.2)disableStatusBar當(dāng)正在通話界面時,使得狀態(tài)欄可用。3.3.3)setIgnoreTouchUserActivity忽略通話過程中無意的觸碰事件,使得這些無意的觸碰不會阻止設(shè)備進入休眠。3.3.4)registerReceiver監(jiān)聽播送3.3.5)startDialerSession當(dāng)在前臺是,保持一個dialersession。首先判斷時候需要播放本地鈴聲,如果需要,則判斷雙音多頻是否可用,如果可用,則創(chuàng)立一個聲音播放器。3.3.6)isBluetoothAudioConnected做一個是否藍牙連接的判斷。3.3.7)如果是cdma通話,則初始化OTA狀態(tài),進而如果是采用了OTA,則設(shè)置InCallScreenMode為OTA通話模型。3.3.8)clearDisconnected在檢查該通話狀態(tài)之前,切斷其他網(wǎng)絡(luò)連接。3.3.9)syncWithPhoneState同步通話界面與Phone的當(dāng)前狀態(tài)。如果沒有同步成功,則dismissAllDialogs();結(jié)束當(dāng)前的所以通話,endInCallScreenSession();關(guān)閉通話界面的顯示。3.3.10)updateWakeState設(shè)置基于當(dāng)前Phone的喚醒狀態(tài)和屏幕超時,以及通話界面的當(dāng)前狀態(tài)。3.3.11)enableTouchLock當(dāng)onresume時“觸摸鎖“疊加是不可見的,尤其是這個檢查可確保用戶通話按MUNU來喚醒屏幕后將不會被鎖。但如果撥號盤是翻開的,而又需要通話計時,則造就了“觸摸鎖“覆蓋。4Pro——該類對通話各個時間點進行記錄。該類對通話各個時間點進行記錄。staticlongsTimeCallScreenRequested;//通話界面被請求的時間staticlongsTimeCallScreenOnCreate;//通話界面被創(chuàng)立的時間staticlongsTimeCallScreenCreated;//通話界面創(chuàng)立完成后的時間staticlongsTimeIncomingCallPanelRequested;//正在通話時,通話界面被請求的時間staticlongsTimeIncomingCallPanelOnCreate;//正在通話時,通話界面被創(chuàng)立的時間staticlongsTimeIncomingCallPanelCreated;//正在通話時,通話界面創(chuàng)立完成后的時間5PhoneUtils.java——負責(zé)Phone對象的生成負責(zé)Phone對象的生成,主要調(diào)用phone.getForegroundCall(),phone.getBackgroundCall(),phone.getRingingCall(),phone.dial()。5.1)placeCall(Phonephone,Stringnumber,UricontactRef)撥打傳入的電話號碼,該函數(shù)被InCallScreen中的placeCall調(diào)用。參數(shù)phone手機對象;參數(shù)number用戶要撥打的號碼;參數(shù)contactRef要么是“tel:〞,要么是“content://contacts〞,取決于通話初始化,該參數(shù)引發(fā)呼叫;返回CALL_STATUS_DIALED,CALL_STATUS_DIALED_MMI,或CALL_STATUS_FAILED。5.2)placeCallVia(Contextcontext,Phonephone,Stringnumber,UricontactRef,UrigatewayUri)使用第三方提供的網(wǎng)關(guān)撥打號碼,該函數(shù)被InCallScreen中的placeCall調(diào)用。如果電話號碼是緊急號碼,GSMMMI碼或者CDMA碼則不能被呼叫。如果連接成立,這個方法發(fā)出一個同步調(diào)用阻止查詢來電信息,使本地采用異步查詢。參數(shù)phone手機對象;參數(shù)context執(zhí)行CallerInfo查詢;參數(shù)number用戶要撥打的號碼,如果號碼不能建立連接,則僅被用于建立電話卡,并更新通話記錄;參數(shù)contactRef要么是“tel:〞,要么是“content://contacts〞,該參數(shù)引發(fā)呼叫;參數(shù)gatewayUri用于設(shè)置連接的地址;返回CALL_STATUS_DIALED或CALL_STATUS_FAILED。6PhoneApp.java——負責(zé)Phone對象頂層應(yīng)用的生成該類是一個普通的java類,主要負責(zé)Phone對象頂層應(yīng)用的生成。這是一個虛擬的Phone對象,它從framework層取得一個Phone對象。該類繼承自Application,同時能常駐內(nèi)存,他和PhoneUtils一起處理電話操作。在oncreate方法里面進行各種全局的初始化:獲取Phone對象NotificationMgr對象,PowerManager對象,SimCard對象等。同時內(nèi)置的Handler可以回調(diào)處理各種事件,如:EVENT_SIM_ABSENT,EVENT_SIM_NETWORK_LOCKED,EVENT_UPDATE_INCALL_NOTIFICATION等。7CallNotifier.java——監(jiān)聽Phone狀態(tài)改變和telephony層事件,觸發(fā)UI行為監(jiān)聽Phone狀態(tài)的改變和來自telephony層各種事件,并觸發(fā)任何有關(guān)的UI行為(如開始的鈴聲和來電的用戶界面,打在通話音,更新通知,寫呼叫記錄條目等)。7.1)在構(gòu)造函數(shù)中,實現(xiàn)mPhone.registerForNewRingingConnection(this,PHONE_NEW_RINGING_CONNECTION,null);/*當(dāng)有新來電或等待連接時Notifies。收到的訊息是:Message.obj將是一個AsyncResult,AsyncResult.userObj=obj,AsyncResult.result=aConnection。因為這個消息已經(jīng)過時,所以通過檢測Connection.isRinging()以確保連接有效。如果Connection.isRinging()為true,那么Connection.getCall()==Phone.getRingingCall()*/mPhone.registerForPreciseCallStateChanged(this,PHONE_STATE_CHANGED,null);/*為通話狀態(tài)的改變注冊notification。通過調(diào)用PreciseCallState以獲取更準(zhǔn)確的通話狀態(tài)。*/mPhone.registerForDisconnect(this,PHONE_DISCONNECT,null);/*當(dāng)由于本地或遠程電話掛斷或者出現(xiàn)錯誤掛斷通話時Notifies。收到的訊息是:Message.objwillbeanAsyncResult,AsyncResult.userObj=obj,AsyncResult.result=aConnectionobjectthatisnolongerconnected.*/mPhone.registerForUnknownConnection(this,PHONE_UNKNOWN_CONNECTION_APPEARED,null);/*當(dāng)以前未跟蹤non-ringing/waiting連接時Notifies。這可能是由于一些其他實體(如SIM卡應(yīng)用)發(fā)起呼叫。*/mPhone.registerForIncomingRing(this,PHONE_INCOMING_RING,null);/*當(dāng)有來電話響鈴時Notifies。收到的訊息是:Message.objwillbeanAsyncResult,AsyncResult.userObj=obj,AsyncResult.result=aConnection.*/另外如果是CDMA通訊類型,還執(zhí)行:mPhone.registerForCdmaOtaStatusChange(this,EVENT_OTA_PROVISION_CHANGE,null);/*當(dāng)CDMAOTA提供者位置改變時注冊notification*/mPhone.registerForCallWaiting(this,PHONE_CDMA_CALL_WAITING,null);/*當(dāng)CDMA呼叫等待時注冊notification*/mPhone.registerForDisplayInfo(this,PHONE_STATE_DISPLAYINFO,null);/*為來自網(wǎng)絡(luò)顯示信息通知注冊。Message.obj將包含一個AsyncResult。AsyncResult.result將是一個SuppServiceNotification實例。*/mPhone.registerForSignalInfo(this,PHONE_STATE_SIGNALINFO,null);/*為來自網(wǎng)絡(luò)的信號信息通知注冊。Message.obj將包含一個AsyncResult。AsyncResult.result將是一個SuppServiceNotification實例。*/mPhone.registerForInCallVoicePrivacyOn(this,PHONE_ENHANCED_VP_ON,null);/*當(dāng)sInCallVoicePrivacy可用時注冊notification*/mPhone.registerForInCallVoicePrivacyOff(this,PHONE_ENHANCED_VP_OFF,null);/*當(dāng)sInCallVoicePrivacy不可用時注冊notification*/mPhone.registerForCdmaFwdBurstDtmf(this,PHONE_CDMA_FWD_BURST_DTMF,null);/*為CDMAForwardBurstDTMF的事件通知設(shè)置處理程序*/mPhone.registerForCdmaFwdContDtmfStart(this,PHONE_CDMA_FWD_CONT_DTMF_START,null);/*為CDMAForwardBurstDTMF啟動的事件通知設(shè)置處理程序*/mPhone.registerForCdmaFwdContDtmfStop(this,PHONE_CDMA_FWD_CONT_DTMF_STOP,null);/*為CDMAForwardBurstDTMF停止的事件通知設(shè)置處理程序*/如果是GSM類型,則執(zhí)行:mPhone.registerForRingbackTone(this,PHONE_RINGBACK_TONE,null);/*當(dāng)帶外回鈴音(專業(yè)術(shù)語CRBT:COLORRINGBACKTONE,回鈴音定義:當(dāng)別人打電話給您時,他(她)聽到的聲音叫做回鈴音?;剽徱羰侵笓艽螂娫挼暮艚蟹剿牭降膶Ψ诫娫挼穆曇?,當(dāng)撥通電話時聽到通話音,通常是長音;而當(dāng)對方占線時則聽到忙音,聲音短促,有時,忙音會變成人聲語音提示。)時Notifies。收到的訊息是:Message.obj將是一個AsyncResult,AsyncResult.userObj=obj,AsyncResult.result=true表示開始播放回鈴音;=false表示停止。*/mPhone.registerForResendIncallMute(this,PHONE_RESEND_MUTE,null);/*為復(fù)位上行靜音狀態(tài)成上行音頻注冊處理程序。*/7.2)整個類由函數(shù)handleMessage串起來。電話局部自動撥號,判斷號碼正確性與否,平安機制。撥打電話過程:一自動撥號是Intent.ACTION_CALL,另一種是Intent.ACTION_DIAl(只是到按鍵盤的界面,需要再手動撥打)以下為CALL的代碼Xml代碼

AndroidManifest.xml

<!--

添加撥出電話的權(quán)限

-->

<uses-permission

android:name="android.permission.CALL_PHONE">

Java代碼

Intent

intent=new

Intent("ent.action.CALL",

Uri.parse("tel:"

+

inputStr));

startActivity(intent);

判斷電話接通狀態(tài)刪除通話記錄負責(zé)存放呼叫記錄的內(nèi)容提供者源碼在

ContactsProvider

工程下:源碼路徑:

com\android\providers\contacts\CallLogProvider.java使用到的數(shù)據(jù)庫在:

/data/data/viders.contacts/databases/contacts2.db

表名:calls

呼叫記錄有三種類型:

來電:CallLog.Calls.INCOMING_TYPE

(常量值:1)

已撥:CallLog.Calls.OUTGOING_TYPE(常量值:2)

未接:CallLog.Calls.MISSED_TYPE(常量值:3)

查看源碼中的聲明:

<providerandroid:name="CallLogProvider"

android:authorities="call_log"

android:syncable="false"android:multiprocess="false"

android:readPermission="android.permission.READ_CONTACTS"

android:writePermission="android.permission.WRITE_CONTACTS">

</provider>3.需要聲明的權(quán)限

<uses-permissionandroid:name="android.permission.READ_CONTACTS"/>

<uses-permissionandroid:name="android.permission.WRITE_CONTACTS"/>4.

系統(tǒng)的通話記錄,是通過

ContentProvider

來對外共享的5.Uri

CallLog.Calls.CONTENT_URI:

等價于:Uri.parse("content://call_log/calls");6.

查詢出所有記錄

ContentResolverresolver=getContentResolver();

resolver.query(CallLog.Calls.CONTENT_URI,null,null,newString[]{""},null);7.

查詢某一個聯(lián)系人的所有記錄(按電話號碼)

resolver.query(CallLog.Calls.CONTENT_URI,null,"number=?",newString[]{""},null);8.

查詢某一個聯(lián)系人的所有未接電話記錄(按電話號碼)

resolver.query(CallLog.Calls.CONTENT_URI,null,"number=?andtype=3",newString[]{""},null);8.

刪除某聯(lián)系人最近的一次來電/*

本代碼因為在

Activity

中,所以可以直接調(diào)用

getContentResolver()。這個方法實際上是

Context

中定義的。

*/

ContentResolver

resolver

=

getContentResolver();

/*

這里涉及到內(nèi)容提供者的知識,其實這里是直接在操作

Android

的數(shù)據(jù)庫,十分痛苦

*/

Cursor

cursor

=

resolver.query(CallLog.Calls.CONTENT_URI,

new

String[]{"_id"},

"number=?

and

(type=1

or

type=3)",

new

String[]{""},

"_id

desc

limit

1");

if(cursor.moveToFirst())

{

int

id

=

cursor.getInt(0);

resolver.delete(CallLog.Calls.CONTENT_URI,

"_id=?",

new

String[]

{id

+

""});

}

短信局部Android設(shè)備接收到的SMS是以pdu形式的(protocoldescriptionunit)(計算機網(wǎng)絡(luò)的概念)(APDUisa"protocoldiscriptionunit",whichistheindustryformatforanSMSmessage.becauseSMSMessagereads/writesthemyoushouldn'tneedtodisectthem.Alargemessagemightbebrokenintomany,whichiswhyitisanarrayofobjects.)android.telephony.gsm.SmsMessage這個類可以儲存SMS的相關(guān)信息,我們也可以從接收到的pdu中創(chuàng)立新的SmsMessage實例SmsMessage的使用比較特殊,并不直接實例化,而是利用靜態(tài)方法getDefault()獲得smsmanager對象發(fā)送短信用戶權(quán)限設(shè)置<uses-permissionandroid:name="android.permission.SEND_SMS"></uses-permission>發(fā)送局部 PendingIntentpi=PendingIntent.getActivity(this,0,newIntent(this,MainActivity.class),0); SmsManagersms=(SmsManager.getDefault()); sms.sendTextMessage(phoneno,null,context,pi,null);publicvoidsendTextMessage(StringdestinationAddress,StringscAddress,Stringtext,PendingIntentsentIntent,PendingIntentdeliveryIntent)destinationAddress:

收件人地址scAddress:

短信中心號碼,空為默認(rèn)中心號碼sentIntent:當(dāng)消息發(fā)出時,成功或者失敗的信息報告通過PendingIntent來播送。如果該參數(shù)為空,則發(fā)信程序會被所有位置程序檢查一遍,這樣會導(dǎo)致發(fā)送時間延長。deliveryIntent:當(dāng)消息發(fā)送到收件人時,該PendingIntent會被播送。pdu數(shù)據(jù)在狀態(tài)報告的extendeddata(“pdu〞)中。拋出IllegalArgumentException

如果收件人或者信息為空。出錯時考慮是不是text長度太長的問題?。〕赃^兩次虧了。。。==發(fā)送彩信刪除短信未嘗試packagepega.android.socket2;importandroid.database.Cursor;import.Uri;importandroid.util.Log;publicclassDeleteMessage{privatePegaSocket2deleteMessage;privateintidelete;privateCursoreventCursor,remindersCursor;privateint[]column=newint[1];privateString[]threadid=newString[1];privateCursorquerymessage;DeleteMessage(PegaSocket2deleteMessage,intid){this.deleteMessage=deleteMessage;idelete=id;StringuriInbox="content://sms";String[]projection=newString[]{"thread_id"};UriuriSms=Uri.parse(uriInbox);Stringwhere="_id="+Integer.toString(idelete);querymessage=deleteMessage.getContentResolver().query(uriSms,projection,where,null,null);}privatevoidMoveToFirst(){querymessage.moveToFirst();}publicintDeleteShortMessage(){if(querymessage.getCount()!=0){MoveToFirst();threadid[0]="thread_id";column[0]=querymessage.getColumnIndex("thread_id");threadid[0]=querymessage.getString(column[0]);//deletemessageintnumber=deleteMessage.getContentResolver().delete(Uri.parse("content://sms/conversations/"+threadid[0]),"_id="+idelete,null);Log.e("delete_number",Integer.toString(number));if(number!=0)return1;elsereturn0;}else{Log.e("number","cann'tfinethemessage!");return0;}}}通過主鍵id來找到他對應(yīng)的thread_id。然后進行刪除就可以了2:監(jiān)聽短信收發(fā)兩種方式利用播送缺點:查看BroadReceiversdkreference,可以了解到所有的BroadReceiver對短信的接收是無順序的狀態(tài),即使是使用了Orderedbroadcasts對于同等優(yōu)先級別的BroadReceiver,也會產(chǎn)生無順序的行為。流程理解:用bundle從intent.getExtras中得到,再用object[]從bundle.get("pdus")得到,此時為pdu形式,接著用SmsMessage.createFromPdu((byte[])pdusObj[i])一位位的讀到SmsMessage[]msg中(每個i表示的是一條短信,此時為smsmessage格式),接著再對每個msg[i].getMessageBody()得到短信的內(nèi)容stringpublicclassreceiveextendsBroadcastReceiver{StringreceiveMsg="";publicvoidonReceive(Contextcontext,Intentintent){SmsMessage[]msg=null;if(intent.getAction().equals("vider.Telephony.SMS_RECEIVED")){Bundlebundle=intent.getExtras();if(bundle!=null){Object[]pdusObj=(Object[])bundle.get("pdus");//bundle中存儲了信息,有傳遞的作用,既然有g(shù)et..,前面一定有存入以這個字符串一個鍵值對的形式儲存了values!把pdus理解為一種標(biāo)識符!msg=newSmsMessage[pdusObj.length];for(inti=0;i<pdusObj.length;i++)msg[i]=SmsMessage.createFromPdu((byte[])pdusObj[i]);}for(inti=0;i<msg.length;i++){StringmsgTxt=msg[i].getMessageBody();

if(msgTxt.equals("Testing!")){Toast.makeText(context,"success!",Toast.LENGTH_LONG).show();return;}else{Toast.makeText(context,msgTxt,Toast.LENGTH_LONG).show();return;}}return;}}利用數(shù)據(jù)庫//如下主要用于內(nèi)部數(shù)據(jù)庫改變,向外面的界面(Activity)做反應(yīng)classSMSHandlerextendsHandler{

publicvoidhandleMessage(Messagemsg)

{

//Handlemessage

}}//對收到短消息后,做出的處理,這里直接刪除,并沒有反應(yīng)到界面,所以上面的handleMessage是空的。classSMSObserverextendsContentObserver{

privateHandlem_handle=null;

publicSMSObserver(Handlehandle)

{

super(handle);

m_handle=handle;

}

publicvoidonChange(booleanbSelfChange)

{

super.onChange(bSelfChange);

//SendmessagetoActivity

Messagemsg=newMessage();

msg.obj="xxxxxxxxxx";

m_handle.sendMessage(msg);StringstrUriInbox="content://sms/inbox";UriuriSms=Uri.parse(strUriInbox);

//IfyouwanttoaccessallSMS,justreplacetheuristringto"content://sms/"Cursorc=mContext.getContentResolver().query(uriSms,null,null,null,null);//deleteallsmsherewheneverynewsmsoccures.while(c.moveToNext()){

//ReadthecontentsoftheSMS;

for(inti;i<c.getColumnCount();i++)

{

StringstrColumnName=c.getColumnName(i);

StringstrColumnValue=c.getString(i);

}

//DeletetheSMS

Stringpid=c.getString(1);

//Getthreadid;

Stringuri="content://sms/conversations/"+pid;

mContext.getContentResolver().delete(Uri.parse(uri),null,null);

}

}}//把根本類功能性地應(yīng)用起來ContentResolvercontentResolver=getContentResolver();//Context環(huán)境下getContentResolver()Handlerhandler=newSMSHandler();ContentObserverm_SMSObserver=newSMSObserver(handler);contentResolver.registerContentObserver(Uri.parse("content://sms/inbox"),true,m_SMSObserver);//RegistertoobserveSMSinoutbox,wecanobserveSMSinotherlocationbychangingUristring,suchasinbox,sent,draft,outbox,etc.)//someAvailableUristring

forsms.REMEBER:mustrequestfollowingpermission1)ReadSMS

<uses-permssionandroid:name="android.permission.READ_SMS"/>2)Delete/Modify/SendSMS

<uses-permssionandroid:name="android.permission.WRITE_SMS"/>inAndroidManifest.xml

1.publicclassScreenTestextendsActivity{

2.

3.

classSmsContentextendsContentObserver{

4.

privateCursorcursor=null;

5.

publicSmsContent(Handlerhandler){

6.

super(handler);

7.

}

8.

9.

/**

10.

*@Description當(dāng)短信表發(fā)送改變時,調(diào)用該方法

11.

*

需要兩種權(quán)限

12.

*

android.permission.READ_SMS讀取短信

13.

*

android.permission.WRITE_SMS寫短信

14.

*@AuthorSnake

15.

*@Date2010-1-12

16.

*/

17.

@Override

18.

publicvoidonChange(booleanselfChange){

19.

//TODOAuto-generatedmethodstub

20.

super.onChange(selfChange);

21.

//讀取收件箱中指定號碼的短信

22.

cursor=managedQuery(Uri.parse("content://sms/inbox"),newString[]{"_id","address","read"},"address=?andread=?",newString[]{"12345678901","0"},"datedesc");

23.

24.

if(cursor!=null){

25.

ContentValuesvalues=newContentValues();

26.

values.put("read","1");

//修改短信為已讀模式

27.

cursor.moveToFirst();

28.

while(cursor.isLast()){

29.

//更新當(dāng)前未讀短信狀態(tài)為已讀

30.

getContentResolver().update(Uri.parse("content://sms/inbox"),values,"_id=?",newString[]{""+cursor.getInt(0)});

31.

cursor.moveToNext();

32.

}

33.

}

34.

}

35.

}

36.

37.

/**Calledwhentheactivityisfirstcreated.*/

38.

@Override

39.

publicvoidonCreate(BundlesavedInstanceState){

40.

super.onCreate(savedInstanceState);

41.

setContentView(R.layout.main);

42.

SmsContentcontent=newSmsContent(newHandler());

43.

//注冊短信變化監(jiān)聽

44.

this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"),true,content);

}

}

收到短信不頂欄通知獲取短信內(nèi)容android的短信都保存在數(shù)據(jù)庫中,通過操作數(shù)據(jù)庫即可獲得短信的信息用android數(shù)據(jù)庫編程嗎,直接調(diào)用provider很方便的。短信的是content://sms/彩信是content://mms/,收件箱是content://sms/inbox已發(fā)送是content://sms/sent發(fā)件箱是content://sms/outbox草稿箱是content://sms/draft短信——結(jié)構(gòu)+數(shù)據(jù)庫相關(guān)相關(guān)的協(xié)議

content://sms/inbox

收件箱content://sms/sent

已發(fā)送(大多數(shù)在這里)content://sms/draft

草稿content://sms/outbox

發(fā)件箱(是要發(fā)的)content://sms/failed

發(fā)送失敗content://sms/queued

待發(fā)送列表在模擬器上Outbox沒有查詢到數(shù)據(jù),在模擬器上找了老半天也沒找到發(fā)件箱,很郁悶。

數(shù)據(jù)庫中sms相關(guān)的字段如下:

_id

一個自增字段,從1開始thread_id

序號,同一發(fā)信人的id相同address

發(fā)件人手機號碼person

聯(lián)系人列表里的序號,陌生人為null

date

發(fā)件日期protocol

協(xié)議,分為:

0

SMS_RPOTO,

1

MMS_PROTO

read

是否閱讀

0未讀,

1已讀

status

狀態(tài)

-1接收,0

complete,

64

pending,

128

failed

type

ALL

=0;

INBOX

=1;

SENT

=2;

DRAFT

=3;

OUTBOX=4;

FAILED=5;

QUEUED=6;

body

短信內(nèi)容service_center

短信效勞中心號碼編號subject

短信的主題reply_path_present

TP-Reply-Pathlocked

_id=490thread_id=31address=1234567892person=null3date=004protocol=05read=06status=-17type=18reply_path_present=09subject=null10body=ertyyhrtsh11service_center=null12locked=013error_code=014seen=015檢索數(shù)據(jù)方法

Uriuri=Uri.parse("content://sms/inbox");

Cursorcur=this.managedQuery(uri,null,null,null,null);

if(cur.moveToFirst()){

do{

for(intj=0;j<cur.getColumnCount();j++){

info="name:"+cur.getColumnName(j)+"="+cur.getString(j);

Log.i("====>",info);

}

}while(cur.moveToNext());

}managedQuery最終也要將參數(shù)轉(zhuǎn)換為SQL語句向SQLite發(fā)送消息,因此參數(shù)跟SQL語句很類似,所以可以在查詢字段中參加SQL函數(shù),比方newString[]projection=newString[]{"count(*)ascount"}等等。

managedQuery中的參數(shù)依次為uri,

查詢字段

查詢字段數(shù)組,也可以將所有需要查詢的字段放入一個字符內(nèi)

比方newprojection[]{"_id","thread_id"}和newprojection[]{"_id,thread_id"}是一致的跟SQL一樣,字段名不區(qū)分大小寫

條件

不帶Where的SQL條件字符,如果有參數(shù)則用?替代,比方"_id=?Andthread_id=?Ortype='1'"

條件中的參數(shù)

參數(shù)字符數(shù)組,跟上述的條件一一對應(yīng)

排序

不帶Orderby排序字符串,比方_iddesc,type

如果參數(shù)為null,SQL中查詢字段為“*〞,相關(guān)的條件為空白getContentResolver()還可以用getContentResolver()獲得一個ContentResolver,

getContentResolver().query()同樣返回一個Cursor對象,參數(shù)跟managedQuery一致。

不過用ContentResolver對象去更新、刪除和插入一條數(shù)據(jù)時報SecurityException??磥頉]有權(quán)限,在Manifest.xml中參加權(quán)限:<uses-permissionandroid:name="android.permission.WRITE_SMS"></uses-permission>

然后刪除短信:this.getContentResolver().delete(Uri.parse("content://sms"),"_id=?",newString[]{"3"});

刪除成功。Url中content://sms

替換成content://sms/

也成功,但是其它url時程序報錯,比方content://sms/inboxsms支持的協(xié)議sURLMatcher.addURI("sms",null,SMS_ALL);sURLMatcher.addURI("sms","#",SMS_ALL_ID);sURLMatcher.addURI("sms","inbox",SMS_INBOX);sURLMatcher.addURI("sms","inbox/#",SMS_INBOX_ID);sURLMatcher.addURI("sms","sent",SMS_SENT);sURLMatcher.addURI("sms","sent/#",SMS_SENT_ID);sURLMatcher.addURI("sms","draft",SMS_DRAFT);sURLMatcher.addURI("sms","draft/#",SMS_DRAFT_ID);sURLMatcher.addURI("sms","outbox",SMS_OUTBOX);sURLMatcher.addURI("sms","outbox/#",SMS_OUTBOX_ID);sURLMatcher.addURI("sms","undelivered",SMS_UNDELIVERED);sURLMatcher.addURI("sms","failed",SMS_FAILED);sURLMatcher.addURI("sms","failed/#",SMS_FAILED_ID);sURLMatcher.addURI("sms","queued",SMS_QUEUED);sURLMatcher.addURI("sms","conversations",SMS_CONVERSATIONS);sURLMatcher.addURI("sms","conversations/*",SMS_CONVERSATIONS_ID);sURLMatcher.addURI("sms","raw",SMS_RAW_MESSAGE);sURLMatcher.addURI("sms","attachments",SMS_ATTACHMENT);sURLMatcher.addURI("sms","attachments/#",SMS_ATTACHMENT_ID);sURLMatcher.addURI("sms","threadID",SMS_NEW_THREAD_ID);sURLMatcher.addURI("sms","threadID/*",SMS_QUERY_THREAD_ID);sURLMatcher.addURI("sms","status/#",SMS_STATUS_ID);sURLMatcher.addURI("sms","sr_pending",SMS_STATUS_PENDING);sURLMatcher.addURI("sms","sim",SMS_ALL_SIM);sURLMatcher.addURI("sms","sim/#",SMS_SIM);其中,delete方法中支持的協(xié)議為:SMS_ALL

根據(jù)參數(shù)中的條件刪除sms表數(shù)據(jù)SMS_ALL_ID

根據(jù)_id刪除sms表數(shù)據(jù)SMS_CONVERSATIONS_ID

根據(jù)thread_id刪除sms表數(shù)據(jù),可以帶其它條件SMS_RAW_MESSAGE

根據(jù)參數(shù)中的條件刪除raw表SMS_STATUS_PENDING

根據(jù)參數(shù)中的條件刪除sr_pending表SMS_SIM

從Sim卡上刪除數(shù)據(jù)試一下SMS_CONVERSATIONS_ID:"content://sms/conversations/3

",刪除thread_id="3",_id="5"的數(shù)據(jù)

在eclipse中的EmulatorControl中,以13800給模擬器發(fā)送三條數(shù)據(jù),然后以13900發(fā)送一條

this.getContentResolver().delete(Uri.parse("content://sms/conversations/3"),"_id=?",newString[]{"5"});

成功刪除一條數(shù)據(jù)。

在數(shù)據(jù)庫中每個發(fā)送者的thread_id雖然一樣,但不是固定的,如果把一個發(fā)送者的全部數(shù)據(jù)刪除掉,

然后換一個新號碼發(fā)送短信時,thread_id是以數(shù)據(jù)庫中最大的id+1賦值的。

update支持的協(xié)議有很多:SMS_RAW_MESSAGE

SMS_ST

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論