日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android短信发送流程之长短信发送(原)

發布時間:2025/3/15 Android 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android短信发送流程之长短信发送(原) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?從前面《 Android短信發送流程之普通短信發送 》流程看到,長短信與普通短信的流程從SmsManager的sendMultipartTextMessage()方法開始區分,現在我們來看長短信的流程: [java]?view plaincopy
  • @SmsManager.java??
  • public?void?sendMultipartTextMessage(?String?destinationAddress,?String?scAddress,?ArrayList<String>?parts,?ArrayList<PendingIntent>?sentIntents,?ArrayList<PendingIntent>?deliveryIntents)?{??
  • ????if?(TextUtils.isEmpty(destinationAddress))?{??
  • ????????throw?new?IllegalArgumentException("Invalid?destinationAddress");??
  • ????}??
  • ????if?(parts?==?null?||?parts.size()?<?1)?{??
  • ????????throw?new?IllegalArgumentException("Invalid?message?body");??
  • ????}??
  • ??
  • ??
  • ????if?(parts.size()?>?1)?{??
  • ????????//長短信發送??
  • ????????try?{??
  • ????????????ISms?iccISms?=?getISmsServiceOrThrow();??
  • ????????????iccISms.sendMultipartText(ActivityThread.currentPackageName(),??
  • ????????????????????destinationAddress,?scAddress,?parts,??
  • ????????????????????sentIntents,?deliveryIntents);??
  • ????????}?catch?(RemoteException?ex)?{??
  • ????????}??
  • ????}?else?{??
  • ????????//普通短信發送??
  • ????????PendingIntent?sentIntent?=?null;??
  • ????????PendingIntent?deliveryIntent?=?null;??
  • ????????if?(sentIntents?!=?null?&&?sentIntents.size()?>?0)?{??
  • ????????????sentIntent?=?sentIntents.get(0);??
  • ????????}??
  • ????????if?(deliveryIntents?!=?null?&&?deliveryIntents.size()?>?0)?{??
  • ????????????deliveryIntent?=?deliveryIntents.get(0);??
  • ????????}??
  • ????????sendTextMessage(destinationAddress,?scAddress,?parts.get(0),?sentIntent,?deliveryIntent);??
  • ????}??
  • }??
  • ? ? ? ? 在上面的方法中,對于長短信將會通過iccISms對象也就是UiccSmsController的sendMultipartText()方法發送出去: [java]?view plaincopy
  • @UiccSmsController.java??
  • public?void?sendMultipartText(String?callingPackage,?String?destAddr,?String?scAddr,?List<String>?parts,?List<PendingIntent>?sentIntents,?List<PendingIntent>?deliveryIntents)?throws?android.os.RemoteException?{??
  • ????sendMultipartTextForSubscriber(getPreferredSmsSubscription(),?callingPackage,?destAddr,?scAddr,?parts,?sentIntents,?deliveryIntents);??
  • }??
  • public?void?sendMultipartTextForSubscriber(long?subId,?String?callingPackage,?String?destAddr,?String?scAddr,?List<String>?parts,?List<PendingIntent>?sentIntents,?List<PendingIntent>?deliveryIntents)?throws?android.os.RemoteException?{??
  • ????IccSmsInterfaceManager?iccSmsIntMgr?=?getIccSmsInterfaceManager(subId);??
  • ????if?(iccSmsIntMgr?!=?null?)?{??
  • ????????iccSmsIntMgr.sendMultipartText(callingPackage,?destAddr,?scAddr,?parts,?sentIntents,??
  • ????????????????deliveryIntents);??
  • ????}?else?{??
  • ????}??
  • }??
  • ? ? ? ? 接下來UiccSmsController又把流程交給IccSmsInterfaceManager的sendMultipartText()來處理: [java]?view plaincopy
  • @IccSmsInterfaceManager.java??
  • public?void?sendMultipartText(String?callingPackage,?String?destAddr,?String?scAddr,?List<String>?parts,?List<PendingIntent>?sentIntents,?List<PendingIntent>?deliveryIntents)?{??
  • ????//權限檢查??
  • ????mPhone.getContext().enforceCallingPermission(?Manifest.permission.SEND_SMS,?"Sending?SMS?message");??
  • ????if?(mAppOps.noteOp(AppOpsManager.OP_SEND_SMS,?Binder.getCallingUid(),?callingPackage)?!=?AppOpsManager.MODE_ALLOWED)?{??
  • ????????return;??
  • ????}??
  • ??
  • ??
  • ????if?(parts.size()?>?1?&&?parts.size()?<?10?&&?!SmsMessage.hasEmsSupport())?{??
  • ????????//當前運營商不支持長短新,需要自行將短信分割后分別發送??
  • ????????for?(int?i?=?0;?i?<?parts.size();?i++)?{??
  • ????????????//?If?EMS?is?not?supported,?we?have?to?break?down?EMS?into?single?segment?SMS??
  • ????????????//?and?add?page?info?"?x/y".??
  • ????????????String?singlePart?=?parts.get(i);??
  • ????????????if?(SmsMessage.shouldAppendPageNumberAsPrefix())?{??
  • ????????????????singlePart?=?String.valueOf(i?+?1)?+?'/'?+?parts.size()?+?'?'?+?singlePart;??
  • ????????????}?else?{??
  • ????????????????singlePart?=?singlePart.concat('?'?+?String.valueOf(i?+?1)?+?'/'?+?parts.size());??
  • ????????????}??
  • ??
  • ??
  • ????????????PendingIntent?singleSentIntent?=?null;??
  • ????????????if?(sentIntents?!=?null?&&?sentIntents.size()?>?i)?{??
  • ????????????????singleSentIntent?=?sentIntents.get(i);??
  • ????????????}??
  • ??
  • ??
  • ????????????PendingIntent?singleDeliveryIntent?=?null;??
  • ????????????if?(deliveryIntents?!=?null?&&?deliveryIntents.size()?>?i)?{??
  • ????????????????singleDeliveryIntent?=?deliveryIntents.get(i);??
  • ????????????}??
  • ??
  • ??
  • ????????????//將長短信分割,挨個發送??
  • ????????????mDispatcher.sendText(destAddr,?scAddr,?singlePart,??
  • ????????????????????singleSentIntent,?singleDeliveryIntent,??
  • ????????????????????null/*messageUri*/,?callingPackage);??
  • ????????}??
  • ????????return;??
  • ????}??
  • ????//運營商支持長短信,直接發送即可??
  • ????mDispatcher.sendMultipartText(destAddr,?scAddr,?(ArrayList<String>)?parts,??
  • ????????????(ArrayList<PendingIntent>)?sentIntents,?(ArrayList<PendingIntent>)?deliveryIntents,??
  • ????????????null/*messageUri*/,?callingPackage);??
  • }??
  • ? ? ? ? 從上面來看,對于長短信, 需要區分運營商是否支持的情況 ,如果不支持,需要我們將短信分割后逐條發送,如果支持,需要走不同流程,由于逐條發送時的流程與普通短信發送流程相同,因此這里主要分析以下運營商支持長短信的情況,也就時sendMultipartText()的流程: [java]?view plaincopy
  • @ImsSMSDispatcher.java??
  • protected?void?sendMultipartText(String?destAddr,?String?scAddr,??
  • ????????ArrayList<String>?parts,?ArrayList<PendingIntent>?sentIntents,??
  • ????????ArrayList<PendingIntent>?deliveryIntents,?Uri?messageUri,?String?callingPkg)?{??
  • ????if?(isCdmaMo())?{??
  • ????????//CDMA??
  • ????????mCdmaDispatcher.sendMultipartText(destAddr,?scAddr,??
  • ????????????????parts,?sentIntents,?deliveryIntents,?messageUri,?callingPkg);??
  • ????}?else?{??
  • ????????//GSM??
  • ????????mGsmDispatcher.sendMultipartText(destAddr,?scAddr,??
  • ????????????????parts,?sentIntents,?deliveryIntents,?messageUri,?callingPkg);??
  • ????}??
  • }??
  • ? ? ? ? 和普通短信類似,也許要區分當前的網絡環境,對于GSM來說,就是使用GsmSMSDispatcher來繼續處理,這個處理是在GsmSMSDispatcher父類SMSDispatcher中完成的: [java]?view plaincopy
  • @SMSDispatcher.java??
  • protected?void?sendMultipartText(String?destAddr,?String?scAddr,?ArrayList<String>?parts,?ArrayList<PendingIntent>?sentIntents,?ArrayList<PendingIntent>?deliveryIntents,?Uri?messageUri,?String?callingPkg)?{??
  • ????//將短信移入或寫入發件箱??
  • ????if?(messageUri?==?null)?{??
  • ????????if?(SmsApplication.shouldWriteMessageForPackage(callingPkg,?mContext))?{??
  • ????????????messageUri?=?writeOutboxMessage(??
  • ????????????????????getSubId(),??
  • ????????????????????destAddr,??
  • ????????????????????getMultipartMessageText(parts),??
  • ????????????????????deliveryIntents?!=?null?&&?deliveryIntents.size()?>?0,??
  • ????????????????????callingPkg);??
  • ????????}??
  • ????}?else?{??
  • ????????moveToOutbox(getSubId(),?messageUri,?callingPkg);??
  • ????}??
  • ????int?refNumber?=?getNextConcatenatedRef()?&?0x00FF;??
  • ????int?msgCount?=?parts.size();??
  • ????int?encoding?=?SmsConstants.ENCODING_UNKNOWN;??
  • ??
  • ??
  • ????TextEncodingDetails[]?encodingForParts?=?new?TextEncodingDetails[msgCount];??
  • ????for?(int?i?=?0;?i?<?msgCount;?i++)?{??
  • ????????TextEncodingDetails?details?=?calculateLength(parts.get(i),?false);??
  • ????????if?(encoding?!=?details.codeUnitSize??
  • ????????????????&&?(encoding?==?SmsConstants.ENCODING_UNKNOWN??
  • ????????????????????||?encoding?==?SmsConstants.ENCODING_7BIT))?{??
  • ????????????encoding?=?details.codeUnitSize;??
  • ????????????????????}??
  • ????????encodingForParts[i]?=?details;??
  • ????}??
  • ??
  • ??
  • ????//?States?to?track?at?the?message?level?(for?all?parts)??
  • ????final?AtomicInteger?unsentPartCount?=?new?AtomicInteger(msgCount);??
  • ????final?AtomicBoolean?anyPartFailed?=?new?AtomicBoolean(false);??
  • ??
  • ??
  • ????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;??
  • ????????//?TODO:?We?currently?set?this?to?true?since?our?messaging?app?will?never??
  • ????????//?send?more?than?255?parts?(it?converts?the?message?to?MMS?well?before?that).??
  • ????????//?However,?we?should?support?3rd?party?messaging?apps?that?might?need?16-bit??
  • ????????//?references??
  • ????????//?Note:??It's?not?sufficient?to?just?flip?this?bit?to?true;?it?will?have??
  • ????????//?ripple?effects?(several?calculations?assume?8-bit?ref).??
  • ????????concatRef.isEightBits?=?true;??
  • ????????SmsHeader?smsHeader?=?new?SmsHeader();??
  • ????????smsHeader.concatRef?=?concatRef;??
  • ??
  • ??
  • ????????//?Set?the?national?language?tables?for?3GPP?7-bit?encoding,?if?enabled.??
  • ????????if?(encoding?==?SmsConstants.ENCODING_7BIT)?{??
  • ????????????smsHeader.languageTable?=?encodingForParts[i].languageTable;??
  • ????????????smsHeader.languageShiftTable?=?encodingForParts[i].languageShiftTable;??
  • ????????}??
  • ??
  • ??
  • ????????PendingIntent?sentIntent?=?null;??
  • ????????if?(sentIntents?!=?null?&&?sentIntents.size()?>?i)?{??
  • ????????????sentIntent?=?sentIntents.get(i);??
  • ????????}??
  • ??
  • ??
  • ????????PendingIntent?deliveryIntent?=?null;??
  • ????????if?(deliveryIntents?!=?null?&&?deliveryIntents.size()?>?i)?{??
  • ????????????deliveryIntent?=?deliveryIntents.get(i);??
  • ????????}??
  • ??
  • ??
  • ????????//逐條發送??
  • ????????sendNewSubmitPdu(destAddr,?scAddr,?parts.get(i),?smsHeader,?encoding,??
  • ????????????????sentIntent,?deliveryIntent,?(i?==?(msgCount?-?1)),??
  • ????????????????unsentPartCount,?anyPartFailed,?messageUri);??
  • ????}??
  • }??
  • ? ? ? ? 在上面的過程中我們看到,對于運營商支持的長短信情況, 需要把拆分出來的短信分別加上短信頭編碼 ,也就是SmsHeader,然后分別調用sendNewSubmitPdu()方法進行發送。
    ? ? ? ? 這里需要簡單介紹以下SmsHeader作用, 普通的短信中SmsHeader為空,所以只有長短信才會有該數據 。他內部確定了該長短信分組的大小、每個分組的索引、編碼格式等信息。
    ? ? ? ? 接下來看sendNewSubmitPdu()的過程,這個方法是在GsmSMSDispatcher中實現的: [java]?view plaincopy
  • protected?void?sendNewSubmitPdu(String?destinationAddress,?String?scAddress,?String?message,?SmsHeader?smsHeader,?int?encoding,?PendingIntent?sentIntent,?PendingIntent?deliveryIntent,?boolean?lastPart,?AtomicInteger?unsentPartCount,?AtomicBoolean?anyPartFailed,?Uri?messageUri)?{??
  • ????//對短信內容進行編碼??
  • ????SmsMessage.SubmitPdu?pdu?=?SmsMessage.getSubmitPdu(scAddress,?destinationAddress,??
  • ????????????message,?deliveryIntent?!=?null,?SmsHeader.toByteArray(smsHeader),??
  • ????????????encoding,?smsHeader.languageTable,?smsHeader.languageShiftTable);??
  • ????if?(pdu?!=?null)?{??
  • ????????HashMap?map?=??getSmsTrackerMap(destinationAddress,?scAddress,?message,?pdu);??
  • ????????//發送??
  • ????????SmsTracker?tracker?=?getSmsTracker(map,?sentIntent,??
  • ????????????????deliveryIntent,?getFormat(),?unsentPartCount,?anyPartFailed,?messageUri,??
  • ????????????????smsHeader,?!lastPart);??
  • ????????sendRawPdu(tracker);??
  • ????}?else?{??
  • ????????Rlog.e(TAG,?"GsmSMSDispatcher.sendNewSubmitPdu():?getSubmitPdu()?returned?null");??
  • ????}??
  • }??
  • ? ? ? ? 接下來的流程和普通短信一樣,最終通過RILJ將短信發送出去,并且注冊回調消息為EVENT_SEND_SMS_COMPLETE。
    ? ? ? ? 也就是說, 對于長短信而言,如果運營商不支持,那么就拆分為一個個普通短信然后逐條發送,如果運營商支持長短信,則會對每個分組短信添加SmsHeader的信息頭,然后逐條發送。

    ? ? ? ? 所以當SMSDispatcher接收到EVENT_SEND_SMS_COMPLETE消息時,就說明,無論是普通短信或者長短信,都已經發送完畢。

    ? ? ? ? 以上就是長短信的發送流程。

    ? ? ? ??多收件人的情況,請見下節介紹。


    Source:?http://blog.csdn.net/u010961631/article/details/50272729

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的Android短信发送流程之长短信发送(原)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: wwwxxx日本人 | 久久99国产综合精品免费 | 国产精品一区二区无码对白 | 男女黄色网| 黄色一级视频片 | 国产毛片毛片毛片毛片毛片 | 91avcom| 激情av网站 | 久久精品五月天 | 国产精品ⅴa有声小说 | 国产亚洲一区二区在线 | 豆花免费跳转入口官网 | 综合在线亚洲 | 久久亚洲综合 | 制服师生在线 | 伊人99| 999国产精品| 久久久久二区 | 日韩精品一区二区三区不卡在线 | 美女激情av | 国产crm系统91在线 | 粉嫩aⅴ一区二区三区 | 日本一区二区在线免费观看 | 美女扒逼| 日本中文字幕在线免费观看 | 欧美日韩精品一区 | 最近中文字幕在线观看 | av在线激情| 亚洲国产精品二区 | 黄色正能量网站 | 日韩一区二 | 少妇av一区二区三区 | 太久av | 国产一级一级片 | 欧美精品成人一区二区在线观看 | 色欲国产精品一区二区 | hs网站在线观看 | 精品免费在线观看 | 锕锕锕锕锕锕锕锕 | 91嫩草欧美久久久九九九 | 国产拍拍拍拍拍拍拍拍拍拍拍拍拍 | 99热97 | 深夜成人福利 | 2025国产精品视频 | 国产在线视频在线观看 | 日本一区二区在线 | 五月婷婷色丁香 | 久久精品视频一区 | 免费看欧美一级特黄a大片 国产免费的av | 激情深爱五月 | 99精品视频99| 成人欧美一区二区三区在线播放 | 边啃奶头边躁狠狠躁 | 欧美特级黄色大片 | 性免费视频 | 热久久精品免费视频 | 久久久久久国产精品三区 | 国产精品久久久久久一区二区 | 日日摸天天爽天天爽视频 | 内射合集对白在线 | 亚洲日本在线观看 | 操女人网| 国产乱码一区二区 | 男女爱爱网站 | 日本一区二区欧美 | 91精品国产欧美一区二区 | 在线观看日韩国产 | 男人狂揉女人下部视频 | 中文字幕日韩欧美一区二区三区 | 国产偷拍一区二区三区 | 黑人操bb| 日韩性生交大片免费看 | 99久久免费看精品国产一区 | 欧美十大老熟艳星 | 99在线国产 | 欧美丰满少妇人妻精品 | 中文字幕va | 日韩av片在线免费观看 | 欧美 日韩 国产 成人 在线观看 | 亚洲免费视频一区二区 | 91尤物视频在线观看 | 国产香蕉久久 | 大乳女喂男人吃奶视频 | 91在线精品入口 | 男人的天堂avav | 四季av国产一区二区三区 | 精品一区二区三区无码视频 | 国产av国片偷人妻麻豆 | 蜜臀久久精品久久久久久酒店 | 我想看一级黄色片 | 四虎福利视频 | 成人午夜sm精品久久久久久久 | 日本特级黄色片 | 成年丰满熟妇午夜免费视频 | 成人毛片视频在线观看 | 国产18在线观看 | 午夜视频在线观看网站 | 日韩免费视频一区二区视频在线观看 | 国产一毛片|