天天看點

長短信發送3,長短信發送

3,長短信發送

在上個章節的論述中, SmsManager的sendMultipartTextMessage方法中有關長短信的發送代碼如下,

ISms iccISms = getISmsServiceOrThrow();
if (iccISms != null) {
      iccISms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
          ActivityThread.currentPackageName(), destinationAddress, scAddress,
          parts, sentIntents, deliveryIntents, priority, isExpectMore, validityPeriod);
}
           

Isms就是phone程序的UiccSmsController服務,是以,最後調用的是phone程序的UiccSmsController的

sendMultipartTextForSubscriberWithOptions方法發送長短信,調用流程圖如下,

長短信發送3,長短信發送

sendMultipartTextForSubscriberWithOptions方法中直接調用IccSmsInterfaceManager的sendMultipartTextWithOptions方法,

主要邏輯如下,

1,首先進行權限檢查,

mPhone.getContext().enforceCallingPermission(Manifest.permission.SEND_SMS,
                "Sending SMS message");
           

2,然後調用ImsSMSDispatcher的sendMultipartText方法,

mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
   (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents,
   null, callingPackage, false /*persistMessage*/, priority, isExpectMore, validityPeriod);
           

在sendMultipartText方法中,根據網絡制式選擇調用不同Dispatcher對象的sendMultipartText方法,

if (isCdmaMo()) {
    mCdmaDispatcher.sendMultipartText(destAddr, scAddr, parts, sentIntents, deliveryIntents, messageUri, callingPkg, persistMessage, priority, isExpectMore, validityPeriod);
} else {
     mGsmDispatcher.sendMultipartText(destAddr, scAddr, parts, sentIntents, deliveryIntents, messageUri, callingPkg, persistMessage, priority, isExpectMore, validityPeriod);
}
           

如果是CDMA網絡,就調用CdmaSMSDispatcher的sendMultipartText方法進行發送;

如果是GSM網絡,就調用GsmSMSDispatcher的sendMultipartText方法進行發送;

其實都是在父類SMSDispatcher實作的, sendMultipartText方法如下,

1, 将拆分出來的短信分别加上短信頭編碼,也就是SmsHeader,

for (int i = 0; i < msgCount; i++) {
    SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
    concatRef.refNumber = refNumber;
    concatRef.seqNumber = i + 1;  // 1-based sequence
concatRef.msgCount = msgCount;
•••
concatRef.isEightBits = true;
SmsHeader smsHeader = new SmsHeader();
smsHeader.concatRef = concatRef;
•••
           

2,分别調用sendSubmitPdu方法發送出去,

for (SmsTracker tracker : trackers) {
   if (tracker != null) {
       sendSubmitPdu(tracker);
•••
           

GsmSMSDispatcher的sendSubmitPdu方法如下,

protected void sendSubmitPdu(SmsTracker tracker) {
    sendRawPdu(tracker);
}
           

直接調用sendRawPdu方法進行發送,這個方法以後的代碼和發送普通短信完全相同。

由此可見,所謂的長短信發送就是将短信進行拆分,然後将拆分的短信像普通短信那樣發送出去。