天天看点

[Android][KK][SMS]Frameworks学习——介绍一、Android SMS架构二、短信数据结构

一、Android SMS架构

二、短信数据结构

三、发送短信流程分析

四、接收短信流程分析

一、Android SMS架构

SMS(Short Messaging Service),短信息服务。在android源代码中已经实现了基本的短信、彩信的发送与接收以及状态报告等相关通信能力,并且将SMS、MMS功能集成在一个应用中的MMS应用。

[Android][KK][SMS]Frameworks学习——介绍一、Android SMS架构二、短信数据结构

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  //