正文  设备功能 > 短信/彩信/SMS/MMS >

Android短信彩信收发流程(应用层)

下图为ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息发送流程。主要以接收者有效性的确认为主,然后转向sendMessage方法进行发送。...

 下图为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处理其余待发送的彩信。
 
\