本篇文章将简单介绍 Android Mashmallow MT(Mobile Terminated) SMS/MMS 的基本流程
一、短信的接收流程
1. RILJ 收到主动上报的消息 UNSOL_RESPONSE_NEW_SMS
在RIL的处理主动上报的消息的方法processUnsolicited,会通过Registrant的方式发送通知给监听者。
mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
通过搜代码可以看到GsmInboundSmsHandler在构造方法里注册监听了这条消息,phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null);
来看一下GsmInboundSmsHandler这个类的注释
/**
* This class broadcasts incoming SMS messages to interested apps after storing them in
* the SmsProvider "raw" table and ACKing them to the SMSC. After each message has been broadcast
*/
大概意思是这个类是用来,在把接收到的短信存到raw表中之后,会发广播给感兴趣的app。并且,在短信广播之后会给短信中心SMSC发送确信消息。
额,介绍就这么多~,还是要具体看看都干啥了。咦
public class GsmInboundSmsHandler extends InboundSmsHandler
public abstract class InboundSmsHandler extends StateMachine
GsmInboundSmsHandler 是状态机的子类,对状态机不熟的可以简单参考另一篇文章哟~http://blog.csdn.net/djialin0418/article/details/51030331
InboundSmsHandler 对这个类的介绍的注释比较多啊,一起看一下。
* This class broadcasts incoming SMS messages to interested apps after storing them in
* the SmsProvider "raw" table and ACKing them to the SMSC. After each message has been
* broadcast, its parts are removed from the raw table. If the device crashes after ACKing
* but before the broadcast completes, the pending messages will be rebroadcast on the next boot.
*
* <p>The state machine starts in {@link IdleState} state. When the {@link SMSDispatcher} receives a
* new SMS from the radio, it calls {@link #dispatchNormalMessage},
* which sends a message to the state machine, causing the wakelock to be acquired in
* {@link #haltedProcessMessage}, which transitions to {@link DeliveringState} state, where the message
* is saved to the raw table, then acknowledged via the {@link SMSDispatcher} which called us.
*
* <p>After saving the SMS, if the message is complete (either single-part or the final segment
* of a multi-part SMS), we broadcast the completed PDUs as an ordered broadcast, then transition to
* {@link WaitingState} state to wait for the broadcast to complete. When the local
* {@link BroadcastReceiver} is called with the result, it sends {@link #EVENT_BROADCAST_COMPLETE}
* to the state machine, causing us to either broadcast the next pending message (if one has
* arrived while waiting for the broadcast to complete), or to transition back to the halted state
* after all messages are processed. Then the wakelock is released and we wait for the next SMS.
*/
主要说了啥?1.状态机的起始状态是IdleState 2. SMS会在DeliveringState存到raw表中? 3.保存完信息之后会检查信息是否完整(如果是长信息,看看各个部分是否完整?)然后把完整的PDU嵌到有序广播中发送出去。4.然后状态机会进如WaitingState等广播完成,当本地的BroadcastReceiver发送EVENT_BROADCAST_COMPLETE给状态机后,会使 广播一条短信(如果这个时候是有一条短信已经接受但是在等当前的这个广播结束),或者处理所有消息后,状态机回到会haltedState。然后wakelock会被释放,并等待下一条短信。
注释文档介绍的还是挺清晰的,下面还是看代码吧~
1. 把短信写到数据库
GsmInboundSmsHandler 处理消息 EVENT_NEW_SMS
IdleState - processMessage -
case EVENT_NEW_SMS:
deferMessage(msg);
transitionTo(mDeliveringState);
状态机要在DeliveringState 处理这条消息 class DeliveringState extends State
/**
* In the delivering state, the inbound SMS is processed and stored in the raw table.
* The message is acknowledged before we exit this state. If there is a message to broadcast,
* transition to {@link WaitingState} state to send the ordered broadcast and wait for the
* results. When all messages have been processed, the halting state will release the wakelock.
*/
case EVENT_NEW_SMS:
handleNewSms((AsyncResult) msg.obj);
sendMessage(EVENT_RETURN_TO_IDLE);
在这个handleNewSms方法中会处理sms,并且处理后会调用RIL的接口来给SMSC短信中心发送确认消息
result = dispatchMessage(sms.mWrappedSmsMessage); //处理短信
notifyAndAcknowledgeLastIncomingSms(handled, result, null); //向SMSC短信中心发送确认消息
主要看一下短信是怎么被处理的
dispatchMessage -> dispatchMessageRadioSpecific(smsb) -> dispatchNormalMessage(smsb)//这里之后便是处理的重点了
InboundSmsTracker tracker;
tracker = new InboundSmsTracker(sms.getPdu(), sms.getTimestampMillis(), destPort,
is3gpp2(), false);
参数里面的3gpp2,3gpp是针对GSM手机的,3gpp2是针对CDMA手机的。
-> addTrackerToRawTableAndSendMessage(tracker) -> addTrackerToRawTable(tracker) //重点之一
看下注释
/**
* Insert a message PDU into the raw table so we can acknowledge it immediately.
* If the device crashes before the broadcast to listeners completes, it will be delivered
* from the raw table on the next device boot. For single-part messages, the deleteWhere
* and deleteWhereArgs fields of the tracker will be set to dele