短信接收流程框架層Frameworks_第1頁
短信接收流程框架層Frameworks_第2頁
短信接收流程框架層Frameworks_第3頁
短信接收流程框架層Frameworks_第4頁
短信接收流程框架層Frameworks_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、Android短信接收流程-框架層(Frameworks)Ps.基于4.1的源碼進(jìn)行分析。涉及的文件html view plain copy print?hardware/ril/libril/ril.cpp 從底層ril.cpp中收到短信處理完成后,通過socket通信到->>Ril.java,框架層的短信接收流程就開始了!1:Ril.javaRil.Java中有內(nèi)部類:RILReceiver,RILReceiver的run方法中不斷的監(jiān)聽: InputStream is = mSocket.getInputStream();然后 readRilMessage(is, buffe

2、r);把消息存入buffer中,然后p.unmarshall(buffer, 0, length);打包成一個Parcel p;然后run方法到最后調(diào)用了processResponse(p);進(jìn)行下一步處理。java view plain copy print? class RILReceiver implements Runnable byte buffer; RILReceiver() buffer = new byteRIL_MAX_COMMAND_BYTES; public void run() int retryCount = 0; try for (;) LocalSocket s

3、 = null; LocalSocketAddress l; try s = new LocalSocket(); l = new LocalSocketAddress(SOCKET_NAME_RIL, LocalSocketAddress.Namespace.RESERVED); s.connect(l); catch (IOException ex) try if (s != null) s.close(); catch (IOException ex2) /ignore failure to close after failure to connect / don't print

4、 an error message after the the first time / or after the 8th time if (retryCount = 8) Log.e (LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL + "' socket after " + retryCount + " times, continuing to retry silently"); else if (retryCount > 0 && retry

5、Count < 8) Log.i (LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL + "' socket; retrying after timeout"); try Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); catch (InterruptedException er) retryCount+; continue; retryCount = 0; mSocket = s; Log.i(LOG_TAG, "Connected to &

6、#39;" + SOCKET_NAME_RIL + "' socket"); int length = 0; try InputStream is = mSocket.getInputStream(); for (;) Parcel p; length = readRilMessage(is, buffer); if (length < 0) / End-of-stream reached break; p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0)

7、; /Log.v(LOG_TAG, "Read packet: " + length + " bytes"); processResponse(p); p.recycle(); catch (java.io.IOException ex) Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed", ex); catch (Throwable tr) Log.e(LOG_TAG, "Uncaught exception read len

8、gth=" + length + "Exception:" + tr.toString(); Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL + "' socket"); setRadioState (RadioState.RADIO_UNAVAILABLE); try mSocket.close(); catch (IOException ex) mSocket = null; RILRequest.resetSerial(); / Clear

9、request list on close clearRequestsList(RADIO_NOT_AVAILABLE, false); catch (Throwable tr) Log.e(LOG_TAG,"Uncaught exception", tr); /* We're disconnected so we don't know the ril version */ notifyRegistrantsRilConnectionChanged(-1); processResponse(p)會根據(jù)類型選擇調(diào)用 processUnsolicited (p)

10、(無需請求直接上報(bào));或是processSolicited (p)(需要先請求才可以);在短信接收過程中調(diào)用的是processUnsolicited (p);processUnsolicited (p)方法會在switch語句中根據(jù)p中的類型進(jìn)行不同的操作,接收短信 會在這個分支中操作case RIL_UNSOL_RESPONSE_NEW_SMS:java view plain copy print? case RIL_UNSOL_RESPONSE_NEW_SMS: if (RILJ_LOGD) unsljLog(response); / FIXME this should move up a

11、 layer String a = new String2; a1 = (String)ret; SmsMessage sms; sms = SmsMessage.newFromCMT(a); if (mGsmSmsRegistrant != null) mGsmSmsRegistrant .notifyRegistrant(new AsyncResult(null, sms, null); break; 把短消息進(jìn)一步封裝處理成一個SmsMessage類型的消息,然后mGsmSmsRegistrant這個是什么呢O O這是一個Registrant類型(消息注冊機(jī)制:一個對象中開辟一個空間用于

12、存放Message,當(dāng)調(diào)用regist方法時(shí)將Message存放進(jìn)去,當(dāng)其調(diào)用notify方法時(shí)將所有Message取出并發(fā)送到MessageQueue中等待處理)暫時(shí)不太明白,我簡單的理解就是把message發(fā)送給handler讓handler去處理。1:那么這個handler在哪里實(shí)現(xiàn)的呢?答:在GsmSMSDispatcher.java(父類:SMSDispather.java)的handleMessage方法中實(shí)現(xiàn)。2:這個handler是在哪里設(shè)置到呢。答:在GsmSMSDispatcher.java的構(gòu)造函數(shù)中調(diào)用了mCm.setOnNewGsmSms(this, EVENT_NE

13、W_SMS, null);而mCm是在手機(jī)開機(jī)時(shí)調(diào)用的PhoneFactory調(diào)用makeDefaultPhone()方法創(chuàng)建的RIL實(shí)例的一個引用,RIL的父類BaseCommands.java(BaseCommands類實(shí)現(xiàn)CommandsInterface的部分接口,通知手機(jī)內(nèi)部狀態(tài)變化)中實(shí)現(xiàn)了public void setOnNewGsmSms(Handler h, int what, Object obj) mGsmSmsRegistrant = new Registrant (h, what, obj); /由此可知在GsmSMSDispatcher.java把handler設(shè)置

14、成了自己 然后短消息就從RIL.java中通過SmsMessage的形式提交到了GsmSMSDispatcher.java與他的父類SMSDispather.java這兩個進(jìn)行短信進(jìn)一步分發(fā)的類中的handleMessage方法中進(jìn)行處理。2:SMSDispatcher.java(父類)GsmSMSDispatcher.java(子類)最開始的handleMessage處理是在SMSDispatcher.java中,直接上SMSDispatcher.java中handleMessage方法的代碼:java view plain copy print? /* * Handles events c

15、oming from the phone stack. Overridden from handler. * * param msg the message to handle * */ Override public void handleMessage(Message msg) AsyncResult ar; switch (msg.what) case EVENT_NEW_SMS: / A new SMS has been received by the device if (false) Log.d(TAG, "New SMS Message Received");

16、 SmsMessage sms; ar = (AsyncResult) msg.obj; if (ar.exception != null) Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception); return; sms = (SmsMessage) ar.result; try int result = dispatchMessage(sms.mWrappedSmsMessage); if (result != Activity.RESULT_OK) / RESULT_OK m

17、eans that message was broadcast for app(s) to handle. / Any other result, we should ack here. boolean handled = (result = Intents.RESULT_SMS_HANDLED); notifyAndAcknowledgeLastIncomingSms(handled, result, null); catch (RuntimeException ex) Log.e(TAG, "Exception dispatching message", ex); no

18、tifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null); break; case EVENT_SEND_SMS_COMPLETE: / An outbound SMS has been successfully transferred, or failed. handleSendComplete(AsyncResult) msg.obj); break; case EVENT_SEND_RETRY: sendSms(SmsTracker) msg.obj); break; case EVE

19、NT_SEND_LIMIT_REACHED_CONFIRMATION: handleReachSentLimit(SmsTracker)(msg.obj); break; case EVENT_SEND_CONFIRMED_SMS: SmsTracker tracker = (SmsTracker) msg.obj; if (tracker.isMultipart() sendMultipartSms(tracker); else sendSms(tracker); mPendingTrackerCount-; break; case EVENT_STOP_SENDING: SmsTracke

20、r tracker = (SmsTracker) msg.obj; if (tracker.mSentIntent != null) try tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED); catch (CanceledException ex) Log.e(TAG, "failed to send RESULT_ERROR_LIMIT_EXCEEDED"); mPendingTrackerCount-; break; 在case EVENT_NEW_SMS:分支語句中:調(diào)用下一步函數(shù)dispatchMessag

21、e()這個方法我們在SMSDispatcher.java中是一個抽象方法,我們很快就能發(fā)現(xiàn)真正的實(shí)現(xiàn)是在子類GsmSMSDispatcher.java中,接著上代碼:java view plain copy print?/* inheritDoc */ Override public int dispatchMessage(SmsMessageBase smsb) / If sms is null, means there was a parsing error. if (smsb = null) Log.e(TAG, "dispatchMessage: message is nul

22、l"); return Intents.RESULT_SMS_GENERIC_ERROR; SmsMessage sms = (SmsMessage) smsb; if (sms.isTypeZero() / As per 3GPP TS 23.040 .9, Type Zero messages should not be / Displayed/Stored/Notified. They should only be acknowledged. Log.d(TAG, "Received short message type 0, Don't display or

23、 store it. Send Ack"); return Intents.RESULT_SMS_HANDLED; / Send SMS-PP data download messages to UICC. See 3GPP TS 31.111 section . if (sms.isUsimDataDownload() UsimServiceTable ust = mPhone.getUsimServiceTable(); / If we receive an SMS-PP message before the UsimServiceTable has been loaded, /

24、 assume that the data download service is not present. This is very unlikely to / happen because the IMS connection will not be established until after the ISIM / records have been loaded, after the USIM service table has been loaded. if (ust != null && ust.isAvailable( UsimServiceTable.Usim

25、Service.DATA_DL_VIA_SMS_PP) Log.d(TAG, "Received SMS-PP data download, sending to UICC."); return mDataDownloadHandler.startDataDownload(sms); else Log.d(TAG, "DATA_DL_VIA_SMS_PP service not available, storing message to UICC."); String smsc = IccUtils.bytesToHexString( PhoneNumb

26、erUworkPortionToCalledPartyBCDWithLength( sms.getServiceCenterAddress(); mCm.writeSmsToSim(SmsManager.STATUS_ON_ICC_UNREAD, smsc, IccUtils.bytesToHexString(sms.getPdu(), obtainMessage(EVENT_WRITE_SMS_COMPLETE); return Activity.RESULT_OK; / acknowledge after response from write to USIM if (mSmsReceiv

27、eDisabled) / Device doesn't support SMS service, Log.d(TAG, "Received short message on device which doesn't support " + "SMS service. Ignored."); return Intents.RESULT_SMS_HANDLED; / Special case the message waiting indicator messages boolean handled = false; if (sms.isMW

28、ISetMessage() mPhone.setVoiceMessageWaiting(1, -1); / line 1: unknown number of msgs waiting handled = sms.isMwiDontStore(); if (false) Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled); else if (sms.isMWIClearMessage() mPhone.setVoiceMessageWaiting(1, 0); / line

29、1: no msgs waiting handled = sms.isMwiDontStore(); if (false) Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled); if (handled) return Intents.RESULT_SMS_HANDLED; if (!mStorageMonitor.isStorageAvailable() && sms.getMessageClass() != MessageClass.CLASS_0) /

30、 It's a storable message and there's no storage available. Bail. / (See TS 23.038 for a description of class 0 messages.) return Intents.RESULT_SMS_OUT_OF_MEMORY; return dispatchNormalMessage(smsb); 沒有管他到底干了什么事情。大概就是判斷是不是一條普普通通的短信而不是什么特別的短信??傊詈笥种匦禄氐礁割怱MSDispatcher.java中調(diào)用了父類方法dispatchNormal

31、Message(smsb);上代碼: java view plain copy print? /* * Dispatch a normal incoming SMS. This is called from the format-specific * link #dispatchMessage(SmsMessageBase) if no format-specific handling is required. * * param sms * return */ protected int dispatchNormalMessage(SmsMessageBase sms) SmsHeader

32、smsHeader = sms.getUserDataHeader(); / See if message is partial or port addressed. if (smsHeader = null) | (smsHeader.concatRef = null) / Message is not partial (not part of concatenated sequence). byte pdus = new byte1; pdus0 = sms.getPdu(); if (smsHeader != null && smsHeader.portAddrs !=

33、null) if (smsHeader.portAddrs.destPort = SmsHeader.PORT_WAP_PUSH) / GSM-style WAP indication return mWapPush.dispatchWapPdu(sms.getUserData(); else / The message was sent to a port, so concoct a URI for it. dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); else / Normal short and non-po

34、rt-addressed message, dispatch it. dispatchPdus(pdus); return Activity.RESULT_OK; else / Process the message part. SmsHeader.ConcatRef concatRef = smsHeader.concatRef; SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs; return processMessagePart(sms.getPdu(), sms.getOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, sms.getTimestampMillis(), (portAddrs != null ? portAddrs.destPort :

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論