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模塊操作