普通短信发送流程

2,普通短信发送流程

在此仅分析普通短信的发送流程, SmsManager 的sendTextMessage方法如下,

ISms iccISms = getISmsServiceOrThrow();
if (iccISms != null) {
    iccISms.sendTextForSubscriberWithOptions(getSubscriptionId(),
       ActivityThread.currentPackageName(), destinationAddress, scAddress, text,
    sentIntent, deliveryIntent, priority, isExpectMore, validityPeriod);
}

首先获取系统的Isms服务,然后调用其sendTextForSubscriberWithOptions方法进行发送。

getISmsServiceOrThrow方法如下,

ISms iccISms = getISmsService();

getISmsService的方法如下,

private static ISms getISmsService() {
    return ISms.Stub.asInterface(ServiceManager.getService("isms"));
}

ISms 对应的服务是UiccSmsController,运行于phone进程中,这样,通过binder跨进程的方法,终于运行到phone进程中了。

并且,其实SmsManager是phone进程提供给app的一个API接口,第三方app可以直接调用SmsManager的sendTextMessage方法发送短信。

对于发短信来说,phone进程的入口是UiccSmsController的sendTextForSubscriberWithOptions方法,调用流程图如下,


sendTextForSubscriberWithOptions方法中直接调用IccSmsInterfaceManager的sendTextWithOptions方法,

iccSmsIntMgr.sendTextWithOptions(callingPackage, destAddr, scAddr, parts, sentIntents,
   deliveryIntents, priority, isExpectMore, validityPeriod);

sendTextWithOptions方法如下,

mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
  null/*messageUri*/, callingPackage, false /*persistMessage*/, priority,
 isExpectMore, validityPeriod);

IccSmsInterfaceManager这个类在创建PhoneProxy的时候进行初始化,其作用是把请求发送给相应的处理者。

mDispatcher 是SMSDispatcher对象, SMSDispatcher总共派生出三个子类:CdmaSMSDispatcher、GsmSMSDispatcher、

ImsSMSDispatcher,在IccSmsInterfaceManager创建时只创建ImsSMSDispatcher,而在ImsSMSDispatcher创建过程中

会对创建其他两种制式的SMSDispatcher,IccSmsInterfaceManager把请求发送给ImsSMSDispatcher后,由

ImsSMSDispatcher根据当前网络状态选择使用CdmaSMSDispatcher还是GsmSMSDispatcher。

ImsSMSDispatcher的sendText方法如下,

if (isCdmaMo()) {
   mCdmaDispatcher.sendText(destAddr, scAddr,
 text, sentIntent, deliveryIntent, messageUri, callingPkg, persistMessage,
priority, isExpectMore, validityPeriod);
} else {
   mGsmDispatcher.sendText(destAddr, scAddr,
        text, sentIntent, deliveryIntent, messageUri, callingPkg, persistMessage,
        priority, isExpectMore, validityPeriod);
}

如果是CDMA网络,就调用CdmaSMSDispatcher的sendText方法进行发送;

如果是GSM网络,就调用GsmSMSDispatcher的sendText方法进行发送;

这两个类的发送流程几乎完全相同,在此以GsmSMSDispatcher的sendText方法为例进行论述。

GsmSMSDispatcher的sendText方法如下,

1,首先调用SmsMessage的getSubmitPdu方法对短信内容进行编码,

SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
  scAddr, destAddr, text, (deliveryIntent != null), validityPeriod);

2,调用sendRawPdu方法进行短信发送,

sendRawPdu(tracker);

短信编码格式很容易导致收发短信问题,因为有些手机仅支持有些特定的格式,对于有些格式的短信无法解析,所以在这个地方要注意。

短信编码

对于GMS来说, SmsMessage就是路径frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm下的SmsMessage.java,

if (encoding == ENCODING_7BIT) {
    userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,
                        languageTable, languageShiftTable);
} else { //assume UCS-2
    try {
        userData = encodeUCS2(message, header);
•••

详细的编码过程以及短信的编码格式在此就不论述了。

短信发送

sendRawPdu方法是在父类SMSDispatcher中实现的,主要对发送的信息以及当前环境进行检测,然后调用子类的sendSms方法, 

sendSmsByPstn方法主要逻辑如下,

1,获取发送的消息,封装EVENT_SEND_SMS_COMPLETE消息,

HashMap<String, Object> map = tracker.mData;

byte smsc[] = (byte[]) map.get("smsc");
byte[] pdu = (byte[]) map.get("pdu");
Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);

2,调用RIL的sendSMS方法发送消息,

mCi.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply);

当然,RIL发送消息之后,会发送EVENT_SEND_SMS_COMPLETE消息,父类SMSDispatcher的handleMessage方法会对该消息进行处理,

case EVENT_SEND_SMS_COMPLETE:
    // An outbound SMS has been successfully transferred, or failed.
    handleSendComplete((AsyncResult) msg.obj);
    break;

handleSendComplete方法在此就不论述了。

RIL的sendSMS方法如下,

public void sendSMS (String smscPDU, String pdu, Message result) {
   RILRequest rr = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);
   constructGsmSendSmsRilRequest(rr, smscPDU, pdu);
   if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
   send(rr);
}

至于Android系统的RIL机制在此就不论述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值