2025-05-23

 

下圖為ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息發送流程。主要以接收者有效性的確認為主,然後轉向sendMessage方法進行發送。
 

 

ComposeMessageActivity.sendMessage
從下圖可以看出,在這個方法中,主要做的事是確認手機狀態的有效性。最終調用WorkingMessage的send方法進行信息的發送。
 

 

WorkingMessage.send
從下圖可以看出,在本方法中,對於不同類型的消息,分別調用不同的方法對其進行處理。並對彩信進行一些簡要的預處理。
 

 
短信部分:
WorkingMessage.preSendSmsWorker
如下圖所示,這是短信部分的發送流程。本方法中所涉及到的東西就比較多瞭。由於已經轉到瞭新線程中利用WorkingMessage進行消息的發送,那麼原來ComposeMessage中的那個WorkingMessage就可以更新瞭。然後確認一下所屬的會話是否存在,如果不存在就新建一個。
接著,將接收者序列化,調用sendSmsWorker。創建一個SmsMessageSender,將消息存入發送隊列中(type字段設為6)。通知SmsReceiver發送。
SmsReceiver則調用SmsReceiverService發送隊列中的第一條短信。
在發送之前,還要根據手機卡的不同,將短信內容分成若幹塊,保證每塊的大小不超過該卡的限制。在分段後的最後一條短信的sentIntent中,設置EXTRA_MESSAGE_SENT_SEND_NEXT為true。這樣當短信發送成功後,會調用SmsReceiverService的handleSmsSent方法,發送隊列中的第一條。
然後,對每塊都指定一個sentIntent,當發送出去之後,修改其狀態。若需要報告,還會指定一個deliveryIntent,用於消息報告的處理。這兩個Intent都會被封裝到SmsTracker中,當發送成功後,在SMSDispatcher的handleSendComplete中被取出。sentIntent會被立即執行,將消息狀態轉為已發送。而deliveryIntent則會被加入deliveryPendingList,等收到消息報告後才被執行(具體代碼在不同的dispatcher中)。
發送完畢後,還要對短信上限、消息顯示列表、草稿進行相應的處理。
 

 

SmsReceiverService.handleSmsSent 消息發送後的處理
當sentIntent被執行後,會根據不同的結果更新消息的所處信箱。
 

 

MessageStatusReceiver 消息報告
當需要接收報告時,會在報告收到之後,在SMSDispatcher中根據不同類型手機從deliveryPendingList中取出並執行相應的deliveryIntent。
 

 

SmsReceiverService.handleSmsReceived 接收短信
當RILReceiver有消息收到時,會從RIL向上傳遞,經由SMSDispatcher的dispatchPdus方法生成Intent調用PrivilegedSmsReceiver。
 

 

彩信部分:
WorkingMessage.sendMmsWorker
從下圖可以看出,彩信發送的過程和短信過程有些類似。都需要重置WorkingMessage,獲取實際ThreadId。發送完都要刪除多餘的信息,調用ComposeMessageActivity的onMessageSent。隻是彩信沒另外創建一個類似preSendSmsWorker的方法,而是把所有內容都放在sendMmsWorker中處理。同時,刪除草稿的位置也有所不同。
 

 

TransactionService.onStartCommand
彩信的發送與短信不同,是以網絡的方式發送的。
每次調用的時候,先取出所有due_time在當前時間之前的待發送的彩信。然後將它的Uri和transactionType封裝到TransactionBundle中,傳給ServiceHandler。類型設為EVENT_TRANSACTION_REQUEST。在ServiceHandler中創建一個SendTransaction對象。然後調用processTransaction方法,根據當前Transaction是否已在隊列中,以及當前的連接狀態確定該把這個SendTransaction對象放到哪個隊列中(mPending為待發送,mProcessing為發送中)。同時使用sendMessageDelayed方法發送一個標記為EVENT_CONTINUE_MMS_CONNECTIVITY的message來保持連接。
接著,將TransactionService放入該Transaction對象的觀察者列表,以便於在後面成功發送後,繼續發送待發送的彩信。
接下來,使用SendTransaction的Run方法從數據庫中獲取指定彩信,並構造SendReq,經由HttpUtils發送編碼後的彩信。根據發送結果,選擇是將錯誤狀態存入數據庫,還是將該彩信轉到已發送箱並通知TransactionService處理待發送的彩信。
 

 

TransactionService.update
該方法執行後,先將Transaction從mProcessing列表中移除。若mPending不空,說明有彩信處於已基本處理但未發送狀態,故調用mServiceHandler,設置EVENT_HANDLE_NEXT_PENDING_TRANSACTION進行處理。從mPending隊列中取出第一個,交由processTransaction處理。由於在之前說過,調用processTransaction的Transaction都會被加入mProcessing隊列,而這個Transaction發送成功後,由會再次通知其觀察者,進而調用TransactionService的update方法繼續發送mPending隊列中的信息。故mPending隊列中的彩信會自動按順序發完。
然後對於成功發送的消息,使用Notification通知用戶(包括消息未讀,消息報告等)。並發送android.intent.action.TRANSACTION_COMPLETED_ACTION的廣播(目前該廣播無人接收,應該是為瞭支持應用開發人員而提供的一種廣播)。
 

 

PushReceiver
android的彩信接收應用層部分從PushReceiver開始。當onReceive被調用後,讓屏幕亮5秒,然後創建一個ReceivePushTask並使用它的execute方法。ReceivePushTask是一個AsyncTask,實現瞭doInBackground方法。當傳入intent後,會在doInBackground中將其中的數據轉成GenericPdu,並根據其消息類型做出不同的操作。
如果是發送報告或已讀報告,將其存入數據庫。
如果是彩信通知,若已存在,則不處理。否則將其存入數據庫。啟動TransactionService進行處理。
TransactionService中的處理主要是調用mServiceHandler,大體過程與發送彩信時相同,隻是此處創建的是NotificationTransaction。
如果不支持自動下載或數據傳輸沒打開,僅通知mmsc。否則,下載相應彩信,刪除彩信通知,通知mmsc,刪除超過容量限制的彩信,通知TransactionService處理其餘待發送的彩信。
 

 

作者 haliluya4

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *