sms接收流程(只包含Java部分)
主要根据打印的mms log,和网上的相关资料对Sms接收流程做一个了解
一个sms的完整接收过程:
radio log
02-26 15:54:20.796 D/AT ( 101): Channel3: AT< +CMT: ,24
02-26 15:54:20.796 D/AT ( 101): Channel3: AT< 0891683108200105F0040D91685108304727F100083120625145012304611F89C9
02-26 15:54:20.796 D/RILC ( 101): [UNSL]< UNSOL_RESPONSE_NEW_SMS {0891683108200105F0040D91685108304727F100083120625145012304611F89C9}
02-26 15:54:20.796 D/RILJ ( 428): [1][UNSL]< [1]UNSOL_RESPONSE_NEW_SMS
02-26 15:54:20.796 D/GSM ( 428): SMS parsePdu
02-26 15:54:20.796 D/GSM ( 428): SMS getSCAddress
02-26 15:54:20.806 D/SMS ( 428): dispatchNormalMessage >>>>>
// 02-26 15:54:20.836 D/GSM ( 539): SMS parsePdu
// 02-26 15:54:20.836 D/GSM ( 539): SMS getSCAddress
1. 最前面1、2、3行属于lib层的处理,这里暂时不作分析
2. 当Java层通过Socket收到下层上报的消息之后,会根据消息的类型调用相关处理函数,
这里调用 handleUnsolicited(Parcel) 处理网络主动上报的消息。
函数处理上报的sms消息:
switch (response)
case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(parcel); break;
这里会走log的第4条
3. 进一步处理消息,将其封装并向上进行通知
switch (response)
case RIL_UNSOL_RESPONSE_NEW_SMS:
String a[] = new String[2];
a[1] = (String) ret;
SmsMessage sms;
sms = SmsMessage.newFromCMT(a);
if (mGsmSmsRegistrant != null) {
mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
}
break;
首先,调用reponseString(Parcel)来解析底层上报的消息,
再, 利用解析的结果封装一个SmsMessage对象,这个对象是:android.telephony.SmsMessage,
其中,会利用com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);来解析字串
并生成相关对象:new SmsMessage(wrappedMessage);
这之中会走log的5、6两条
4. 通知上层新消息到来,
mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
mGsmSmsRegistrant的注册:
GsmSMSDispatcher.java: mCM.setOnNewGsmSms(this, EVENT_NEW_SMS, null);
BaseCommands.java: mGsmSmsRegistrant = new Registrant(h, what, obj);
这样,当新消息来临时,就可以通过这个注册来通知了
5. GsmSMSDispatcher.java收到消息,进行处理(实际上是SMSDispatcher.java)
调用栈
int result = dispatchMessage(sms.mWrappedMessage);
return dispatchNormanMessage(smsb); // 打印第7条
dispatchPdus(pdus);
dispatch(intent, RECEIVE_SMS_PERMISSION);
mContext.sendOrderedBroadcast(intent, permission, mResultReceiver, this, Activity.RESULT_OK, null, null);
最后,我们可以看出这个方法将短信通过顺序广播播放出去(action是SMS_RECEIVED_ACTION)。