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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android短信发送流程之多收件人发送(原)

發(fā)布時間:2025/3/15 Android 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android短信发送流程之多收件人发送(原) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?? ? ? 前面的《 Android短信發(fā)送流程之長短信發(fā)送 》中介紹了長短信對于普通短信的區(qū)別,而對于多收件人的情況,在SmsMessageSender的queueMessage()方法中我們了解到,發(fā)送之前,將多收件人的短信進(jìn)行拆分,放入"content://sms/queued"隊列中,在接下來的流程中,將會在SmsReceiverService中通過sendFirstQueuedMessage()方法取出隊列中的第一條短信并發(fā)送,那么,隊列中的其他消息是如何被發(fā)送出去的呢?
? ? ? ? 我們從第一條短信發(fā)送完畢后的流程來尋找答案。
? ? ? ? 由于在GsmSMSDispatcher向RILJ發(fā)送消息時所注冊的回應(yīng)消息是EVENT_SEND_SMS_COMPLETE,所以當(dāng)短信發(fā)送成功時,就會收到該消息的回應(yīng)。
? ? ? ? 在SMSDispatcher中對該回應(yīng)進(jìn)行處理: [java]?view plaincopy
  • @SMSDispatcher.java??
  • public?void?handleMessage(Message?msg)?{??
  • ????switch?(msg.what)?{??
  • ????????case?EVENT_SEND_SMS_COMPLETE:??
  • ????????????//發(fā)送成功??
  • ????????????handleSendComplete((AsyncResult)?msg.obj);??
  • ????????????break;??
  • ????????default:??
  • ????????????Rlog.e(TAG,?"handleMessage()?ignoring?message?of?unexpected?type?"?+?msg.what);??
  • ????}??
  • }??
  • ? ? ? ? 然后進(jìn)入handleSendComplete()方法中處理: [java]?view plaincopy
  • protected?void?handleSendComplete(AsyncResult?ar)?{??
  • ????SmsTracker?tracker?=?(SmsTracker)?ar.userObj;??
  • ????PendingIntent?sentIntent?=?tracker.mSentIntent;??
  • ??
  • ??
  • ????if?(ar.result?!=?null)?{??
  • ????????tracker.mMessageRef?=?((SmsResponse)ar.result).mMessageRef;??
  • ????}?else?{??
  • ????}??
  • ??
  • ??
  • ????if?(ar.exception?==?null)?{??
  • ????????//發(fā)送成功??
  • ????????if?(tracker.mDeliveryIntent?!=?null)?{??
  • ????????????//將當(dāng)前短信的tracker保存??
  • ????????????deliveryPendingList.add(tracker);??
  • ????????}??
  • ????????//回調(diào)到SmsTracker內(nèi)部??
  • ????????tracker.onSent(mContext);??
  • ????}?else?{??
  • ????????//發(fā)送失敗??
  • ????}??
  • }??
  • ? ? ? ? 在上面的過程中,對短信發(fā)送的結(jié)果進(jìn)行區(qū)分,如果失敗,將會根據(jù)失敗原因通知SmsTracker,如果成功,將會進(jìn)入SmsTracker中繼續(xù)處理: [java]?view plaincopy
  • public?void?onSent(Context?context)?{??
  • ????boolean?isSinglePartOrLastPart?=?true;??
  • ????if?(mUnsentPartCount?!=?null)?{??
  • ????????//判斷是否已經(jīng)將長短新最后一條發(fā)送完畢??
  • ????????isSinglePartOrLastPart?=?mUnsentPartCount.decrementAndGet()?==?0;??
  • ????}??
  • ????if?(isSinglePartOrLastPart)?{??
  • ????????//當(dāng)前所有短信發(fā)送完畢,更新數(shù)據(jù)庫狀態(tài)??
  • ????????boolean?success?=?true;??
  • ????????if?(mAnyPartFailed?!=?null?&&?mAnyPartFailed.get())?{??
  • ????????????success?=?false;??
  • ????????}??
  • ????????if?(success)?{??
  • ????????????setMessageFinalState(context,?Sms.MESSAGE_TYPE_SENT);??
  • ????????}?else?{??
  • ????????????setMessageFinalState(context,?Sms.MESSAGE_TYPE_FAILED);??
  • ????????}??
  • ????}??
  • ????//把發(fā)送短信之前保存在SmsTracker中的Intent取出來發(fā)送出去,通知短信已經(jīng)發(fā)送成功。??
  • ????if?(mSentIntent?!=?null)?{??
  • ????????try?{??
  • ????????????//?Extra?information?to?send?with?the?sent?intent??
  • ????????????Intent?fillIn?=?new?Intent();??
  • ????????????if?(mMessageUri?!=?null)?{??
  • ????????????????//?Pass?this?to?SMS?apps?so?that?they?know?where?it?is?stored??
  • ????????????????fillIn.putExtra("uri",?mMessageUri.toString());??
  • ????????????}??
  • ????????????if?(mUnsentPartCount?!=?null?&&?isSinglePartOrLastPart)?{??
  • ????????????????//?Is?multipart?and?last?part??
  • ????????????????fillIn.putExtra(SEND_NEXT_MSG_EXTRA,?true);??
  • ????????????}??
  • ????????????mSentIntent.send(context,?Activity.RESULT_OK,?fillIn);??
  • ????????}?catch?(CanceledException?ex)?{??
  • ????????????Rlog.e(TAG,?"Failed?to?send?result");??
  • ????????}??
  • ????}??
  • }??
  • ? ? ? ? 由于此時無論是長短信還是普通短信,都已經(jīng)發(fā)送完畢(只發(fā)送了一個收件人),因此isSinglePartOrLastPart的判定將會是true,從而更新數(shù)據(jù)庫中該短信的狀態(tài),然后再將發(fā)送時附加在SmsTracker中的mSentIntent取出來并發(fā)送出去,同時指定返回結(jié)果為“Activity.RESULT_OK”。
    ? ? ? ? 而這里的mSentIntent就是在SmsSingleRecipientSender中指定的,我們再來回顧以下當(dāng)時的狀態(tài): [java]?view plaincopy
  • @SmsSingleRecipientSender.java??
  • public?boolean?sendMessage(long?token)?throws?MmsException?{??
  • ????if?(mMessageText?==?null)?{??
  • ????????throw?new?MmsException("Null?message?body?or?have?multiple?destinations.");??
  • ????}??
  • ????SmsManager?smsManager?=?SmsManager.getDefault();??
  • ????ArrayList<String>?messages?=?null;??
  • ????//拆分長短信??
  • ????if?((MmsConfig.getEmailGateway()?!=?null)?&&?(Mms.isEmailAddress(mDest)?||?MessageUtils.isAlias(mDest)))?{??
  • ????????//彩信??
  • ????????String?msgText;??
  • ????????msgText?=?mDest?+?"?"?+?mMessageText;??
  • ????????mDest?=?MmsConfig.getEmailGateway();??
  • ????????messages?=?smsManager.divideMessage(msgText);??
  • ????}?else?{??
  • ????????//短信??
  • ????????messages?=?smsManager.divideMessage(mMessageText);??
  • ????????mDest?=?PhoneNumberUtils.stripSeparators(mDest);??
  • ????????mDest?=?Conversation.verifySingleRecipient(mContext,?mThreadId,?mDest);??
  • ????}??
  • ????int?messageCount?=?messages.size();??
  • ??
  • ??
  • ????if?(messageCount?==?0)?{??
  • ????????throw?new?MmsException("SmsMessageSender.sendMessage:?divideMessage?returned?"?+?"empty?messages.?Original?message?is?\""?+?mMessageText?+?"\"");??
  • ????}??
  • ??
  • ??
  • ????boolean?moved?=?Sms.moveMessageToFolder(mContext,?mUri,?Sms.MESSAGE_TYPE_OUTBOX,?0);??
  • ????if?(!moved)?{??
  • ????????throw?new?MmsException("SmsMessageSender.sendMessage:?couldn't?move?message?"?+?"to?outbox:?"?+?mUri);??
  • ????}??
  • ????ArrayList<PendingIntent>?deliveryIntents?=??new?ArrayList<PendingIntent>(messageCount);??
  • ????ArrayList<PendingIntent>?sentIntents?=?new?ArrayList<PendingIntent>(messageCount);??
  • ????for?(int?i?=?0;?i?<?messageCount;?i++)?{??
  • ????????if?(mRequestDeliveryReport?&&?(i?==?(messageCount?-?1)))?{??
  • ????????????//所有短信被發(fā)送完畢后,在最后一條短信后面添加送達(dá)報告的Intent??
  • ????????????deliveryIntents.add(PendingIntent.getBroadcast(??
  • ????????????????????????mContext,?0,??
  • ????????????????????????new?Intent(??
  • ????????????????????????????MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,??
  • ????????????????????????????mUri,??
  • ????????????????????????????mContext,??
  • ????????????????????????????MessageStatusReceiver.class),??
  • ????????????????????????0));??
  • ????????}?else?{??
  • ????????????deliveryIntents.add(null);??
  • ????????}??
  • ????????//對于拆分后的短消息,需要在每條信息發(fā)送完畢后發(fā)送該Intent,從而接著發(fā)送剩下的拆分短信??
  • ????????Intent?intent??=?new?Intent(SmsReceiverService.MESSAGE_SENT_ACTION,??
  • ????????????????mUri,??
  • ????????????????mContext,??
  • ????????????????SmsReceiver.class);??
  • ??
  • ??
  • ????????int?requestCode?=?0;??
  • ????????if?(i?==?messageCount?-1)?{??
  • ????????????//收到該附加數(shù)據(jù)說明當(dāng)前的拆分短信已經(jīng)發(fā)送完畢??
  • ????????????requestCode?=?1;??
  • ????????????intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT,?true);??
  • ????????}??
  • ????????sentIntents.add(PendingIntent.getBroadcast(mContext,?requestCode,?intent,?0));??
  • ????}??
  • ????try?{??
  • ????????//發(fā)送??
  • ????????smsManager.sendMultipartTextMessage(mDest,?mServiceCenter,?messages,?sentIntents,?deliveryIntents);??
  • ????}?catch?(Exception?ex)?{??
  • ????????throw?new?MmsException("SmsMessageSender.sendMessage:?caught?"?+?ex?+?"?from?SmsManager.sendTextMessage()");??
  • ????}??
  • ????return?false;??
  • }??
  • ? ? ? ? 從這里我們看到,當(dāng)前的mSentIntent發(fā)送對象是SmsReceiver,內(nèi)容是MESSAGE_SENT_ACTION,而且包含了附加數(shù)據(jù)EXTRA_MESSAGE_SENT_SEND_NEXT=true,并且SmsTracker發(fā)送該Intent時傳送的結(jié)果是“Activity.RESULT_OK”。
    ? ? ? ? 由于SmsReceiver會把所有Intent轉(zhuǎn)交給SmsReceiverService處理,我們直接來看SmsReceiverService的處理: [java]?view plaincopy
  • @SmsReceiverService.java??
  • public?void?handleMessage(Message?msg)?{??
  • ????int?serviceId?=?msg.arg1;??
  • ????Intent?intent?=?(Intent)msg.obj;??
  • ????if?(intent?!=?null?&&?MmsConfig.isSmsEnabled(getApplicationContext()))?{??
  • ????????String?action?=?intent.getAction();??
  • ????????int?error?=?intent.getIntExtra("errorCode",?0);??
  • ??
  • ??
  • ????????if?(MESSAGE_SENT_ACTION.equals(intent.getAction()))?{??
  • ????????????//處理??
  • ????????????handleSmsSent(intent,?error);??
  • ????????}?else?if?(SMS_DELIVER_ACTION.equals(action))?{??
  • ????????????handleSmsReceived(intent,?error);??
  • ????????}?else?if?(ACTION_BOOT_COMPLETED.equals(action))?{??
  • ????????????handleBootCompleted();??
  • ????????}?else?if?(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action))?{??
  • ????????????handleServiceStateChanged(intent);??
  • ????????}?else?if?(ACTION_SEND_MESSAGE.endsWith(action))?{??
  • ????????????handleSendMessage();??
  • ????????}?else?if?(ACTION_SEND_INACTIVE_MESSAGE.equals(action))?{??
  • ????????????handleSendInactiveMessage();??
  • ????????}??
  • ????}??
  • ????SmsReceiver.finishStartingService(SmsReceiverService.this,?serviceId);??
  • }??
  • ? ? ? ? 對于當(dāng)前的Intent,將會在handleSmsSent()中處理: [java]?view plaincopy
  • private?void?handleSmsSent(Intent?intent,?int?error)?{??
  • ????Uri?uri?=?intent.getData();??
  • ????mSending?=?false;??
  • ????//EXTRA_MESSAGE_SENT_SEND_NEXT表示是否是長短新的最后一條??
  • ????boolean?sendNextMsg?=?intent.getBooleanExtra(EXTRA_MESSAGE_SENT_SEND_NEXT,?false);??
  • ????if?(mResultCode?==?Activity.RESULT_OK)?{??
  • ????????//將已經(jīng)發(fā)送成功的短信移入發(fā)件箱,更新其狀態(tài)為已發(fā)送??
  • ????????if?(!Sms.moveMessageToFolder(this,?uri,?Sms.MESSAGE_TYPE_SENT,?error))?{??
  • ????????????Log.e(TAG,?"handleSmsSent:?failed?to?move?message?"?+?uri?+?"?to?sent?folder");??
  • ????????}??
  • ????????if?(sendNextMsg)?{??
  • ????????????//繼續(xù)發(fā)送其他收件人??
  • ????????????sendFirstQueuedMessage();??
  • ????????}??
  • ????????//?Update?the?notification?for?failed?messages?since?they?may?be?deleted.??
  • ????????MessagingNotification.nonBlockingUpdateSendFailedNotification(this);??
  • ????}?else?if?((mResultCode?==?SmsManager.RESULT_ERROR_RADIO_OFF)?||??
  • ????????????(mResultCode?==?SmsManager.RESULT_ERROR_NO_SERVICE))?{??
  • ????????//?We?got?an?error?with?no?service?or?no?radio.?Register?for?state?changes?so??
  • ????????//?when?the?status?of?the?connection/radio?changes,?we?can?try?to?send?the??
  • ????????//?queued?up?messages.??
  • ????????registerForServiceStateChanges();??
  • ????????//?We?couldn't?send?the?message,?put?in?the?queue?to?retry?later.??
  • ????????Sms.moveMessageToFolder(this,?uri,?Sms.MESSAGE_TYPE_QUEUED,?error);??
  • ????????mToastHandler.post(new?Runnable()?{??
  • ????????????public?void?run()?{??
  • ????????????????Toast.makeText(SmsReceiverService.this,?getString(R.string.message_queued),??
  • ????????????????????Toast.LENGTH_SHORT).show();??
  • ????????????}??
  • ????????});??
  • ????}?else?if?(mResultCode?==?SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE)?{??
  • ????????messageFailedToSend(uri,?mResultCode);??
  • ????????mToastHandler.post(new?Runnable()?{??
  • ????????????public?void?run()?{??
  • ????????????????Toast.makeText(SmsReceiverService.this,?getString(R.string.fdn_check_failure),??
  • ????????????????????Toast.LENGTH_SHORT).show();??
  • ????????????}??
  • ????????});??
  • ????}?else?{??
  • ????????messageFailedToSend(uri,?error);??
  • ????????if?(sendNextMsg)?{??
  • ????????????sendFirstQueuedMessage();??
  • ????????}??
  • ????}??
  • }??
  • ? ? ? ? 由于當(dāng)前resultCode=OK,并且sendNextMsg=true,首先會通過Sms.moveMessageToFolder()操作將發(fā)送成功的短信從"content://sms/queued"隊列移動到"content://sms/sent"隊列。
    ? ? ? ? 然后在sendFirstQueuedMessage()中繼續(xù)處理: [java]?view plaincopy
  • public?synchronized?void?sendFirstQueuedMessage()?{??
  • ????boolean?success?=?true;??
  • ????final?Uri?uri?=?Uri.parse("content://sms/queued");??
  • ????ContentResolver?resolver?=?getContentResolver();??
  • ????Cursor?c?=?SqliteWrapper.query(this,?resolver,?uri,?SEND_PROJECTION,?null,?null,?"date?ASC");???//?date?ASC?so?we?send?out?in??
  • ????if?(c?!=?null)?{??
  • ????????try?{??
  • ????????????if?(c.moveToFirst())?{??
  • ????????????????//從隊列中取出第一個并發(fā)送??
  • ????????????????String?msgText?=?c.getString(SEND_COLUMN_BODY);??
  • ????????????????String?address?=?c.getString(SEND_COLUMN_ADDRESS);??
  • ????????????????int?threadId?=?c.getInt(SEND_COLUMN_THREAD_ID);??
  • ????????????????int?status?=?c.getInt(SEND_COLUMN_STATUS);??
  • ??
  • ??
  • ????????????????int?msgId?=?c.getInt(SEND_COLUMN_ID);??
  • ????????????????Uri?msgUri?=?ContentUris.withAppendedId(Sms.CONTENT_URI,?msgId);??
  • ??
  • ??
  • ????????????????SmsMessageSender?sender?=?new?SmsSingleRecipientSender(this,??
  • ????????????????????????address,?msgText,?threadId,?status?==?Sms.STATUS_PENDING,??
  • ????????????????????????msgUri);??
  • ????????????????try?{??
  • ????????????????????sender.sendMessage(SendingProgressTokenManager.NO_TOKEN);;??
  • ????????????????????mSending?=?true;??
  • ????????????????}?catch?(MmsException?e)?{??
  • ????????????????????mSending?=?false;??
  • ????????????????????messageFailedToSend(msgUri,?SmsManager.RESULT_ERROR_GENERIC_FAILURE);??
  • ????????????????????success?=?false;??
  • ????????????????????//?Sending?current?message?fails.?Try?to?send?more?pending?messages??
  • ????????????????????//?if?there?is?any.??
  • ????????????????????sendBroadcast(new?Intent(SmsReceiverService.ACTION_SEND_MESSAGE,??
  • ????????????????????????????????null,??
  • ????????????????????????????????this,??
  • ????????????????????????????????SmsReceiver.class));??
  • ????????????????}??
  • ????????????}??
  • ????????}?finally?{??
  • ????????????c.close();??
  • ????????}??
  • ????}??
  • ????if?(success)?{??
  • ????????//?We?successfully?sent?all?the?messages?in?the?queue.?We?don't?need?to??
  • ????????//?be?notified?of?any?service?changes?any?longer.??
  • ????????unRegisterForServiceStateChanges();??
  • ????}??
  • }??
  • ? ? ? ? 在上面的過程中,檢測發(fā)送隊列中是否有未發(fā)送的短信,對于多收件人的情況,由于我們之前只發(fā)送出去了第一條短信,而且已經(jīng)將已發(fā)送的短信從該隊列移出,因此此時的隊列中只有其他收件人的短信,然后取出其中的一條,再次進(jìn)入發(fā)送通道,接下來的流程和之前的相同。

    ? ? ? ? 這就是多收件人的發(fā)送流程。


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

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: sm乳奴虐乳调教bdsm | 久久久久久久久久艹 | 国产传媒在线观看 | 特级淫片裸体免费看冫 | 一级全黄男女免费大片 | 少妇15p | 国产精品一区二区在线观看 | 国产视频最新 | 国产成人免费看 | 小香蕉影院 | 午夜久久久久久久久久 | av秋霞 | 香蕉视频在线播放 | 成人在线观看a | 金瓶狂野欧美性猛交xxxx | 久久久久久免费观看 | 免费久久精品视频 | 天堂va蜜桃一区二区三区漫画版 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 四虎精品永久在线 | 日本视频在线免费观看 | 国产无码精品在线观看 | 成人免费无码大片a毛片抽搐色欲 | 精品人妻一区二区三区四区久久 | 日日日日日日 | 久久久久久久久久久影院 | 黄色免费成人 | 2022天天操| 色悠悠久久综合 | japanesexxxx日本妞 | 日本午夜视频在线观看 | 邻居少妇张开腿让我爽了在线观看 | 欧美日韩一区二区不卡 | 捆绑少妇玩各种sm调教 | 日韩作爱 | 少妇高潮久久久 | 2021天天干| 国产原创在线播放 | 麻豆传媒网址 | 久久综合精品视频 | 啪啪免费 | 可以免费看的av | 女女互慰揉小黄文 | 日本少妇ⅹxxxxx视频 | 日本特级黄色 | 精品国产综合区久久久久久 | 姐姐av| 精品国产一 | 91高跟黑色丝袜呻吟动态图 | 91成人短视频在线观看 | 久久77777 | 日本免费在线观看视频 | 青青草原伊人 | 国产chinesehd精品露脸 | 最新国产网址 | 国产免费一区二区三区四区五区 | 一区二区av | 亚洲成人一区二区在线观看 | 国产人妻aⅴ色偷 | 后入内射无码人妻一区 | 黄色一及片 | 国产无遮挡又黄又爽免费视频 | 欧美日韩在线视频一区二区 | 国产精品免费在线播放 | 亚洲综合色小说 | 一本大道熟女人妻中文字幕在线 | 激情久久一区 | 黄色网免费观看 | 欧美xxxx黑人xyx性爽 | 爱情岛论坛自拍亚洲品质极速最新章 | 午夜毛片在线 | 国产精品午夜在线 | 日本高清视频一区二区三区 | 18欧美性xxxx极品hd | 一区二区一级片 | 91亚色视频在线观看 | 亚洲第一天堂av | 精品在线视频一区二区三区 | 免费国产羞羞网站视频 | 亚洲激情视频在线 | 亚洲码无人客一区二区三区 | 国产性生活 | 最好看十大无码av | 午夜精品99| 非洲黄色大片 | 欧美视频在线一区二区三区 | 久久123| 人人插人人干 | 午夜性色福利影院 | 亚洲乱码一区 | 中出中文字幕 | 天天操导航 | 美女高潮在线 | 女同hd系列中文字幕 | 狠狠gao | 在线观看深夜视频 | 污视频在线观看网址 | 香蕉色网| 丝袜性爱视频 |