一、Android SMS架構
二、短信資料結構
三、發送短信流程分析
四、接收短信流程分析
一、Android SMS架構
SMS(Short Messaging Service),短資訊服務。在android源代碼中已經實作了基本的短信、彩信的發送與接收以及狀态報告等相關通信能力,并且将SMS、MMS功能內建在一個應用中的MMS應用。
SMS的分層結構與Android架構保持一緻, 從上到下依次是:MMS應用層、Telephony Frameworks架構層、RIL層。app層如何将發送短信轉換成RIL請求以及app如何接收RIL發出的新短信通知相關的代碼主要集中在Java Frameworks層,是以本次學習主要關注Frameworks層。
SMS在Telephony Frameworks層主要有以下幾個類:
1.SmsMessage.java(frameworks/opt/telephony/src/java/android/telephony):定義了短信在framework層的資料結構。
2.SmsMessageBase.java:容納實際的短信資料。它有兩個子類 SmsMessage.java(frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm)和SmsMessage.java(frameworks/opt/telephony/src/java/com/android/internal/telephony/cdma),負責幫助SmsMessage.java(frameworks/opt/telephony/src/java/android/telephony)來處理GSM/CDMA制式下的資料解析。
3.SmsManager.java:發送短信的唯一入口。SmsManager類在Telephony Frameworks層提供短信操作的相關接口供application層調用,application層通過擷取此類的對象,完成對短信的操作。該類提供了短信拆分、短信發送、将短信複制到SIM卡、從SIM卡删除短信和小區廣播等接口。
4.IccSmsInterfaceManager.java:抽象類,實作了ISms.stub接口,它有兩個子類:RuimSmsInterfaceManager和SimSmsInterfaceManager,分别對應USIM卡和SIM卡的操作,不同之處在于電話卡中的短信存儲和讀取以及小區廣播的實作邏輯。
5.SMSDispatcher.java:繼承Handler類,有三個子類:ImsSMSDispatcher、GsmSMSDispatcher和CdmaSMSDispatcher。與RIL.java互動,完成短信的發送和接收。
6.RIL.java:通過socket與RILC互動,完成短信發送請求與RIL請求之間的轉換。
二、短信資料結構
1.SMS資料結構
在telephony.java中,定義了SMS存儲到資料庫時的主要屬性和方法。
SMS的屬性:
1. TYPE //The type of the message
2. THREAD_ID //The thread ID of the message
3. ADDRESS //The address of the other party
4. PERSON_ID //The person ID of the sender
5. DATE //The date the message was received
6. READ //Has the message been read
7. STATUS //The status of the message
8. SUBJECT //The subject of the message
9. BODY //The body of the message
10.PROTOCOL //The protocol identifier code
11.SERVICE_CENTER // The service center
12.REPLY_PATH_PRESENT //Whether TP-Reply-Path bit was set
13.LOCKED //Has the message been locked
14.SUB_ID //
SMS的方法:
1.query() //
2.addMessageToUri() //将短信内容儲存至資料庫
3.moveMessageToFolder() //将短信内容轉移另一個URI
4.isOutgoingFolder() //
2.SmsMessage資料結構
在SmsMessage.java(frameworks/opt/telephony/src/java/android/telephony)中,定義了SmsMessage向下傳遞資料時的主要屬性和方法。
SmsMessage的屬性:
1.mWrappedSmsMessage //SmsMessageBase對象,容納實際的短信資料。
2.MessageClass //enum:UNKNOWN,CLASS_0,CLASS_1,CLASS_2,CLASS_3
3.ENCODING_XXX //XXbit編碼:7BIT/8BIT/16BIT/UNKNOWN
4.MAX_USER_DATA_BYTES //短信最大位元組數140
5.MAX_USER_DATA_BYTES_WITH_HEADER //帶header的短信最大位元組數134
6.MAX_USER_DATA_SEPTETS //短信最大7位位元組數160
7.MAX_USER_DATA_SEPTETS_WITH_HEADER //帶header的短信最大7位位元組數153
8.FORMAT_3GPP/FORMAT_3GPP2 //短信format
9.mSubId //subId
SmsMessage的方法:
1.SmsMessage() //
2.createFromPdu() //
3.getXXX() //mWrappedSmsMessage.getXXX()
4.isXXX() //mWrappedSmsMessage.isXXX()
其中, 屬性中的ENCODING_7BIT/ENCODING_8BIT/ENCODING_16BIT分别代表着手機短信的PDU編碼方式:7-bit、8-bit和16-bit編碼。7-bit編碼用于發送普通的ASCII字元,即英文短信,最多可發送160字 符。8-bit編碼通常用于發送資料消息。16-bit編碼用于發送Unicode字元,可發送中文字元,最多發送70字元。PDU格式參照表1-1
元素 | 名稱 | 長度 | 描述 |
SCA | Service Center Address | 1-12 | 短消息服務中心号碼 |
PDU-Type | Protocol Data Unit | 1 | 協定資料單元類型 |
MR | Message Reference | 1 | 所有成功的短信發送參考數目(0..255) |
OA | Originator Address | 2-12 | 發送方位址(手機号碼) |
DA | Destination Address | 2-12 | 接收方位址(手機号碼) |
PID | Protocol Identifer | 1 | 參數顯示消息中心以何種方式處理消息内容(比如FAX,Voice) |
DCS | Data Coding Scheme | 1 | 參數顯示使用者資料編碼方案 |
SCTS | Service Center Time Stamp | 7 | 消息中心收到消息時的時間戳 |
VP | Validity Period | 0,1,7 | 參數顯示消息有效期 |
UDL | User Data Lenghth | 1 | 使用者資料長度 |
UD | User Data | 0-140 | 使用者資料 |
表1 發送方PDU格式
在PDU中,DCS資料編碼方案占據8bit。其中Bit N0.1與Bit No.0表示短信的類型,即屬性中的MessageClass:
00-Class 0:Immediate Display,短信内容自動顯示在螢幕上,看完自動消失
01-Class 1:Mobile Equipment-specific,會存儲在裝置上的短信
10-Class 2:SIM specific Message,會存儲在SIM卡的短信
11-Class 3:Terminate Equipment-specific,直接到終端裝置上的短信
而Bit No.3與Bit No.2則表示PDU編碼方式,即屬性中的 ENCODING_XXX:
00-ENCODING_7BIT:預設的字元集,每字元占7bit,此時最大可發送160字元(即屬性MAX_USER_DATA_SEPTETS=160)
01-ENCODING_8BIT:8bit,此時最大可發送140字元(即屬性MAX_USER_DATA_BYTES=140)
10-ENCODING_16BIT:16bit,發送雙位元組字元集
11-ENCODING_UNKNOWN:預留
3.SmsMessageBase
在SmsMessage中,有一個重要屬性基本上所有的方法都會用到它:SmsMessageBase對象mWrappedSmsMessage。SmsMessageBase定義了SmsMessage基本的屬性和方法。
SmsMessageBase的屬性:
1.scAddress //SMSC
2.originatingAddress //sender
3.messageBody //messageBody
4.mPdu //The raw PDU of the message
5.userData //The raw bytes for the user data
…
SmsMessageBase的方法:
1.getXXX() //return 屬性
2.isXXX() //
4.SmsMessageBase的兩個子類
由于通信機制分為GSM和CDMA兩種,是以SmsMessage也分了兩種:
com.android.internal.telephony.cdma.SmsMessage
com.android.internal.telephony.gsm.SmsMessage
在SmsMessage的一些關于處理資料的方法中,會根據短信的format來判斷調用gsm.SmsMessage的方法還是cdma.SmsMessage的方法。二者的主要差別就是對資料的解析方式實作不同,如parseXX()。
gsm.SmsMessage的parseUserData方法會根據ENCODING_XXX的不同,來調用不同的解析方法,得到正确的短信資料。
5.SmsTracker類
在SMSDispatcher和RIL互動的過程中,不管是将短信發送請求轉換至RIL請求,還是回調短信狀态,SmsTracker對象一直被傳遞。現在分析一下SmsTracker類的資料結構。
SmsTracker類是RIL.java的一個protected内部類。該類隻有一個SmsTracker構造方法和一個判斷是否是分段短信的isMultipart方法,其餘的是聲明的成員變量。
mData //包含着destAddr/scAddr/text/smsc/pdu的HASHMAP
mSentIntent //短信發送狀态的回調intent
mDeliveryIntent //短信發送狀态的回調intent
mRetryCount //短信重發次數計數
mAppInfo //app package info
mDestAddress //短信收件人
mFormat //GSM or CDMA
mImsRetry //
mMessageRef //