版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《數(shù)列最后沖刺》課件
- 《計算機C語言》課件
- 河北省遵化市堡子店中學(xué)2025屆高考仿真模擬英語試卷含解析
- 2025屆河北省廊坊市六校聯(lián)考高三下學(xué)期一模考試數(shù)學(xué)試題含解析
- 《solidworks 機械設(shè)計實例教程》 課件 任務(wù)11.1 單缸搖擺蒸汽機運動仿真的設(shè)計
- 上海市崇明區(qū)市級名校2025屆高三最后一卷英語試卷含解析
- 《solidworks 機械設(shè)計實例教程》 課件 任務(wù)6.2 密封壓蓋的設(shè)計
- 忻州一中2025屆高考仿真卷數(shù)學(xué)試題含解析
- 吉林省遼源市2025屆高三下第一次測試數(shù)學(xué)試題含解析
- 云南省開遠一中2025屆高三3月份第一次模擬考試英語試卷含解析
- 穿脫隔離衣及注意事項培訓(xùn)課件穿脫隔離衣的注意事項有哪些
- 實訓(xùn)報告計算機網(wǎng)絡(luò)直連兩臺計算機
- 高中生學(xué)習(xí)思想?yún)R報范文(12篇)
- 2023大地電磁測深法技術(shù)規(guī)程
- 機械加工工藝過程卡片+工序卡
- 燒傷面積的計算
- 藥店培訓(xùn)資料
- Office辦公軟件應(yīng)用(Office2010)中職全套教學(xué)課件
- 子癇應(yīng)急預(yù)案
- 土石方工程挖掘機人員車輛信息登記表
- 數(shù)控加工理實一體化建設(shè)方案
評論
0/150
提交評論