SMS_UI---Layout
conversation_list_screen.xml 显示对话列表
conversation_list_actionbar.xml 未读对话列表的选中高亮 id:unread_conv_count
conversation_list_multi_select_actionbar.xml 已选会话列表的选中高亮 id:selected_conv_count
conversation_list_item.xml 每组会话在列表中都是图片+from+date+subject的形式
compose_message_activity.xml 编辑框 发送(id:send_button_sms) 全选 取消 删除
SMS---Src
(1)UI入口
ComposeMessageActivity extends Activity(com.android.mms.ui)
onCreate()
initMessageSettings()加载setting中的设置
initResourceRefs() 初始化UI控件
mSendButtonSms = (ImageButton) findViewById(R.id.send_button_sms);
mSendButtonSms.setOnClickListener(this);
| (mUiHander表示一个主线程的Handle对象)
onClick(View v) --> mUiHandler.sendEmptyMessageDelayed(MSG_RESUME_SEND_BUTTON, RESUME_BUTTON_INTERVAL);
等待指定的时间(1秒)之后发送消息到子线程
sendMessage()允许你处理Message对象(Message里可以包含数据)sendEmptyMessage()只能放数据
|
SaveMsgThread extends Thread 启动消息队列机制
(2)待传送的信息
WorkingMessage (com.android.mms.data)即将发送的短信类
(3)发送信息
SmsMessageSender implements MessageSender(com.android.mms.transaction)为短信的发送作准备,使sms进入消息队列,分离接收人
SmsSingleRecipientSender extends MessageSender 发送一条短信,最终用framework的SmsManager来发送信息
(4)接收信息
SmsReceiver extends BroadcastReceiver(com.android.mms.transaction)请求sms service的入口
PrivilegedSmsReceiver extends SmsReceiver(com.android.mms.transaction)接收短信的类
SmsReceiverService extends Service(com.android.mms.transaction)sms的处理中心,处理信息的 send/receive,处理一些来自framework层的的通知。
MessageStatusReceiver extends BroadcastReceiver(com.android.mms.transaction)捕获信息,并读取信息的状态
SMS---解读
(1)发送信息的流程
用户在ComposeMessageActivity中new一个WorkingMessage对象
WorkingMessage又new一个SmsMessageSender对象
PendingIntent是一个发送异步intent的类
本质上就是使用MessageSender接口发送信息,实现该接口必须实例化两个方法,分别是sendMessage(long token)和setSimId(int simId)
在framework层发送信息的方法 对应于android.telephony.SmsMessage;
所有发送的消息最终都要保存至消息队列,SmsReceiver--> SmsReceiverService --> SmsSingleRecipientSender -->framework:SmsManager
(2) 接收信息的流程
本质上是靠PrivilegedSmsReceiver类来接收信息
在framework层接收信息的方法 对应于android.telephony.SmsMessage;
所有接收的消息最终都要保存到消息队列,SmsReceiverService --> SmsSingleRecipientSender -->framework:SmsManager
(3)数据库的存取
所有的消息,最终都会保存在sqlite中,对应的数据库操作涉及framework
framework:SqliteWrapper(android.database.sqlite)
framework:ContentResovler(android.content)
framework:SQliteDatabase提供query()方法
MMS---初探
数据库层Mms和Sms的区别在于,sms直接用query()和update(),而mms则使用PduPersister(android.mms.pdu)类
MMS主要的处理都在app层,在framework层中主要涉及MMS pdu包的解析处理和发送和接受MMS时的网络处理。
pdu---(protocol description unit)可以从接收到的pdu中创建新的SmsMessage实例,Toast界面组件可以以系统通知的形式来显示接收到的SMS消息文本。
对MMS的操作直接就是对mmssms.db数据库的操作
(1)push MMS 接收
MMS通知消息是以短信息PDU包的形式传递过来的(M-Notification.ind PDU),Android中的具体处理流程如下:
1)当有新信息来的时候,atchannel的reader线程会调用onUnsolicited()函数处理。
2)onUnsolicited()函数调用RIL_onUnsolicitedResponse()函数,并传入RIL_UNSOL_RESPONSE_NEW_SMS值及相应数据。
3)RIL_onUnsolicitedResponse()调用sendResponse()函数,通过socket(socket名:SOCKET_NAME_RIL)向ril.java层传递数据。
4)ril java层通过RILReceiver接收器从socket中读出数据,处理后调用ril类中的processResponse()方法,processResponse()方法调用processUnsolicited()方法。
5)在processUnsolicited()方法中,执行下面语句:
case RIL_UNSOL_RESPONSE_NEW_SMS: {
if (RILJ_LOGD) unsljLog(response);
String a[] = new String[2];
a[1] = (String)ret;
SmsMessage sms;
sms = SmsMessage.newFromCMT(a); //根据SMS协议解析PDU包
if (mSMSRegistrant != null) {
mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
}
break;
其中mSMSRegistrant实例是在初始化的时候创建的,其中存储着SMSDispatcher handler对象和EVENT_NEW_SMS事件信息。
随后通过message消息机制和handler处理机制把EVENT_NEW_SMS事件传递到了SMSDispatcher handler类 处理。
6)SMSDispatcher handler接收到EVENT_NEW_SMS事件,调用handleMessage()方法处理,handleMessage()方法调用其子类dispatchMessage()方法。
7)在dispatchMessage()中,根据smsHeader.portAddrs(PORT_WAP_PUSH = 2948)地址来判断是否是PUSH信息。
8)调用WapPushOverSms类的dispatchWapPdu()方法。
9)使用WspTypeDecoder类实例来对PUSH信息进行解析,并根据content type来判断是否是MMS PUSH信息。
10)调用dispatchWapPdu_MMS()方法,通过SMSDispatcher类的dispatch()方法来广播发送intent. WAP_PUSH_RECEIVED_ACTION。
11)PushReceiver接收到该intent,启动ReceivePushTas并执行doInBackground()方法。
12)在doInBackground()方法中,通过PduParser类对象解析对应的PDU包,然后执行如下代码:
case MESSAGE_TYPE_NOTIFICATION_IND: {
NotificationInd nInd = (NotificationInd) pdu;
if (!isDuplicateNotification(mContext, nInd)) {
Uri uri = p.persist(pdu, Inbox.CONTENT_URI); //MMS PUSH信息存储在inbox.
Intent svc = new Intent(mContext, TransactionService.class);//intent启动的是TransactionService。
svc.putExtra(TransactionBundle.URI, uri.toString());
svc.putExtra(TransactionBundle.TRANSACTION_TYPE,
Transaction.NOTIFICATION_TRANSACTION);//transaction类型:NOTIFICATION_TRANSACTION
mContext.startService(svc);//启动TransactionService服务
}
13)TransactionService类中的onStart()调用launchTransaction()方法
14)launchTransaction()方法传递给ServiceHandler EVENT_TRANSACTION_REQUEST事件。
15)ServiceHandler类的handleMessage()方法处理EVENT_TRANSACTION_REQUEST事件,根据Transaction的类型为NOTIFICATION_TRANSACTION,
创建NotificationTransaction类实例,并根据URI从mmssms.db中取出PDU包。
16)调用processTransaction(transaction)方法,在processTransaction()方法中,执行如下代码:
int connectivityResult = beginMmsConnectivity();//通过beginMmsConnectivity函数进行data connection。
if (connectivityResult == Phone.APN_REQUEST_STARTED) { //如果返回APN_REQUEST_STARTED结果,表示data connection正在连接,等待返回EVENT_DATA_STATE_CHANGED事件
mPending.add(transaction);//把transaction放入等待队列中
return true; //返回,等待EVENT_DATA_STATE_CHANGED事件再继续处理
}
transaction.attach(TransactionService.this); //因为Transaction 类和TransactionService 类都继承自Observable类,
//此处是为了Transaction类的子类在处理完成后通知TransactionService相应的处理结果。
transaction.process(); //进入NotificationTransaction类中处理,创建一个新的线程来处理该transaction。
17)下面的处理请参照MMS相关transaction中的NotificationTransaction说明。
(2)从MMSC中提取MMS
根据DownloadManager类中的mAutoDownload变量的值,从MMSC中提取MMS有两种情况:
1)如果mAutoDownload为TRUE,即允许自动提取,那么在indication通知上来的时候,就会从MMSC向提取MMS信息。
即使在NotificationTransaction中所做的处理。具体请参照MMS相关transaction中的NotificationTransaction说明
2)否则,就需要手动去从MMSC中提取。具体处理如下:此时UI层会启动TransactionService,并传入Transaction.RETRIEVE_TRANSACTION类型。
其他的处理流程参考第一条(push MMS接收)中的第13到第17步,只不过相应的transaction是RetrieveTransaction,而非NotificationTransaction。
(3)MMS发送
MMS的发送动作是由UI来触发的,主要是有ComposeMessageActivity类中的sendMmsWorker()方法来处理。具体处理流程如下:
1. sendMmsWorker()方法中,创建MmsMessageSender类实例sender,并调用MmsMessageSender类中的sendMessage()方法。
2.从mmssms.db中取出对应的PDU数据,把信息移到outbox中(以前是存储在draft下),然后启动TransactionService服务进行transaction处理。
3.通过TransactionService处理进入了SendTransaction类的run()方法中处理。
(4)MMS存储/删除等数据操作
MMS信息的存储是以SQLite3为基础的,而且其mmssms.db数据库在第一次创建后会一直存在,这就对MMS的存储处理变得简单很多,只需要执行相应的SQL语句就行。
MMS中的内容部分是存储在file中的,并没有放在mmssms.db数据库中,数据库中存放的是如下几张表:
static final String TABLE_PDU = "pdu";//PDU相关信息的表
static final String TABLE_ADDR = "addr";//MMS发件人/收件人地址相关的表
static final String TABLE_PART = "part"; //body可能分成几个部分,存储part相关信息的表,通过该part信息,就可以从file中取到对应的内容部分
static final String TABLE_RATE = "rate"; // SENT_TIME信息表
static final String TABLE_DRM = "drm";
(5)MMS参数设置
MMS的参数设置也是通过SQLite3数据库进行操作的,其content provider类:TelephonyProvider,其DatabaseHelper类是其内部类。
TelephonyProvider对应的CONTENT_URI在Telephony 类的Carriers内部类中。
MMS参数的设置主要在setting模块操作