您的位置:首页 > 移动开发 > Android开发

短信接收流程分析

2017-08-09 21:22 183 查看

5,短信接收

如果有信息,RIL层会主动上报消息,RIL.java 的processUnsolicited方法会进行分发,根据网络制式,信息分为GSM和CDMA,

在此就以GSM信息为例论述, processUnsolicited方法对RIL_UNSOL_RESPONSE_NEW_SMS消息处理逻辑如下,

1,调用responseString方法从ril层读取消息内容,

case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
responseString方法如下,

private Object
responseString(Parcel p) {
String response;
response = p.readString();
return response;
}

2,将消息转为SmsMessage对象,然后发送出去,

case RIL_UNSOL_RESPONSE_NEW_SMS: {
if (RILJ_LOGD) unsljLog(response);

// FIXME this should move up a layer
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));
}

那么,谁会对该消息进行处理呢? 谁注册谁处理。

在RIL的父类BaseCommands的setOnNewGsmSms方法中,

public void setOnNewGsmSms(Handler h, int what, Object obj) {
mGsmSmsRegistrant = new Registrant (h, what, obj);
}

并且在GsmInboundSmsHandler的构造方法中,调用了setOnNewGsmSms方法,

private GsmInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
PhoneBase phone) {
super("GsmInboundSmsHandler", context, storageMonitor, phone,
GsmCellBroadcastHandler.makeGsmCellBroadcastHandler(context, phone));
phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null);
mDataDownloadHandler = new UsimDataDownloadHandler(phone.mCi);
}

因此,当RIL上报消息时,会向GsmInboundSmsHandler发送EVENT_NEW_SMS消息。

在父类InboundSmsHandler中处理, InboundSmsHandler是一个状态机,

public abstract class InboundSmsHandler extends StateMachine {

并且DeliveringState状态会对EVENT_NEW_SMS消息进行处理,处理流程图如下,



DeliveringState的processMessage对EVENT_NEW_SMS消息处理如下,

case EVENT_NEW_SMS:
// handle new SMS from RIL
handleNewSms((AsyncResult) msg.obj);
sendMessage(EVENT_RETURN_TO_IDLE);
return HANDLED;

handleNewSms方法主要是调用dispatchMessage方法分发消息,

SmsMessage sms = (SmsMessage) ar.result;
result = dispatchMessage(sms.mWrappedSmsMessage);

dispatchMessage方法处理逻辑如下,

if (mSmsReceiveDisabled) {
// Device doesn't support receiving SMS,
log("Received short message on device which doesn't support "+ "receiving SMS. Ignored.");
return Intents.RESULT_SMS_HANDLED;
}

return dispatchMessageRadioSpecific(smsb);

dispatchMessageRadioSpecific是一个抽象的方法,在具体的子类中实现,

在InboundSmsHandler的dispatchNormalMessage方法主要逻辑如下,

1,将普通短信PDU解析封装成InboundSmsTracker对象,

if ((smsHeader == null) || (smsHeader.concatRef == null)) {
// Message is not concatenated.
int destPort = -1;
if (smsHeader != null && smsHeader.portAddrs != null) {
// The message was sent to a port.
destPort = smsHeader.portAddrs.destPort;
if (DBG) log("destination port: " + destPort);
}
tracker = new InboundSmsTracker(sms.getPdu(), sms.getTimestampMillis(), destPort,
is3gpp2(), false);

2,如果是长短信,将长短信PDU解析封装成InboundSmsTracker对象,

SmsHeader.ConcatRef concatRef = smsHeader.concatRef;
SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs;
int destPort = (portAddrs != null ? portAddrs.destPort : -1);

tracker = new InboundSmsTracker(sms.getPdu(), sms.getTimestampMillis(), destPort,
is3gpp2(), sms.getOriginatingAddress(), concatRef.refNumber,
concatRef.seqNumber, concatRef.msgCount, false);

3,调用addTrackerToRawTableAndSendMessage方法发送消息,

return addTrackerToRawTableAndSendMessage(tracker);

addTrackerToRawTableAndSendMessage方法中会发送EVENT_BROADCAST_SMS消息,

sendMessage(EVENT_BROADCAST_SMS, tracker);

DeliveringState对EVENT_BROADCAST_SMS消息处理如下,

case EVENT_BROADCAST_SMS:
// if any broadcasts were sent, transition to waiting state
InboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj;
if (processMessagePart(inboundSmsTracker)) {
transitionTo(mWaitingState);
•••

调用processMessagePart方法进行处理, InboundSmsHandler 的processMessagePart方法如下,

int messageCount = tracker.getMessageCount();
byte[][] pdus;
int destPort = tracker.getDestPort();

if (messageCount == 1) {//普通短信
// single-part message
pdus = new byte[][]{tracker.getPdu()};
else { //长短信
•••
String address = tracker.getAddress();
String refNumber = Integer.toString(tracker.getReferenceNumber());
String count = Integer.toString(tracker.getMessageCount());
•••
dispatchSmsDeliveryIntent(pdus, tracker.getFormat(), destPort, resultReceiver);

最后调用dispatchSmsDeliveryIntent方法进行处理,该方法如下,

Intent intent = new Intent();
intent.putExtra("pdus", pdus);
intent.putExtra("format", format);
•••
intent.setAction(Intents.DATA_SMS_RECEIVED_ACTION);
Uri uri = Uri.parse("sms://localhost:" + destPort);
intent.setData(uri);
intent.setComponent(null);
•••
dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS,
AppOpsManager.OP_RECEIVE_SMS, options, resultReceiver, UserHandle.OWNER);

最后调用dispatchIntent方法发送广播,

dispatchIntent方法如最后会调用sendOrderedBroadcastAsUser发送广播。

这样, 在应用层注册这些广播就可以处理收到的信息。Mms中对接收短信的处理在此就不论述了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android Mms 短信发送