SMS的源碼研究

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
每組會話在列表中都是圖片+fromdatesubject的形式
compose_message_activity.xml
編輯框 發送(id:send_button_sms) 全選 取消 刪除

SMS---Src
1UI入口
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
發送一條短信,最終用frameworkSmsManager來發送信息
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)發送信息的流程
用戶在ComposeMessageActivitynew一個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---初探
數據庫層MmsSms的區別在於,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
)當有新信息來的時候,atchannelreader線程會調用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類實例,並根據URImmssms.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
)如果mAutoDownloadTRUE,即允許自動提取,那麼在indication通知上來的時候,就會從MMSC向提取MMS信息。
即使在NotificationTransaction中所做的處理。具體請參照MMS相關transaction中的NotificationTransaction說明
2
)否則,就需要手動去從MMSC中提取。具體處理如下:此時UI層會啓動TransactionService,並傳入Transaction.RETRIEVE_TRANSACTION類型。
其他的處理流程參考第一條(push MMS接收)中的第13到第17步,只不過相應的transactionRetrieveTransaction,而非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_URITelephony 類的Carriers內部類中。
MMS
參數的設置主要在setting模塊操作

 




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章