Android短信发送流程之多收件人发送(原)
生活随笔
收集整理的這篇文章主要介紹了
Android短信发送流程之多收件人发送(原)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?? ? ? 前面的《
Android短信發(fā)送流程之長(zhǎng)短信發(fā)送
》中介紹了長(zhǎng)短信對(duì)于普通短信的區(qū)別,而對(duì)于多收件人的情況,在SmsMessageSender的queueMessage()方法中我們了解到,發(fā)送之前,將多收件人的短信進(jìn)行拆分,放入"content://sms/queued"隊(duì)列中,在接下來的流程中,將會(huì)在SmsReceiverService中通過sendFirstQueuedMessage()方法取出隊(duì)列中的第一條短信并發(fā)送,那么,隊(duì)列中的其他消息是如何被發(fā)送出去的呢?
? ? ? ? 我們從第一條短信發(fā)送完畢后的流程來尋找答案。
? ? ? ? 由于在GsmSMSDispatcher向RILJ發(fā)送消息時(shí)所注冊(cè)的回應(yīng)消息是EVENT_SEND_SMS_COMPLETE,所以當(dāng)短信發(fā)送成功時(shí),就會(huì)收到該消息的回應(yīng)。
? ? ? ? 在SMSDispatcher中對(duì)該回應(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ā)送失敗?? ????}?? }??
? ? ? ? 在上面的過程中,對(duì)短信發(fā)送的結(jié)果進(jìn)行區(qū)分,如果失敗,將會(huì)根據(jù)失敗原因通知SmsTracker,如果成功,將會(huì)進(jìn)入SmsTracker中繼續(xù)處理:
[java]?view plaincopy public?void?onSent(Context?context)?{?? ????boolean?isSinglePartOrLastPart?=?true;?? ????if?(mUnsentPartCount?!=?null)?{?? ????????//判斷是否已經(jīng)將長(zhǎ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");?? ????????}?? ????}?? }??
? ? ? ? 由于此時(shí)無論是長(zhǎng)短信還是普通短信,都已經(jīng)發(fā)送完畢(只發(fā)送了一個(gè)收件人),因此isSinglePartOrLastPart的判定將會(huì)是true,從而更新數(shù)據(jù)庫中該短信的狀態(tài),然后再將發(fā)送時(shí)附加在SmsTracker中的mSentIntent取出來并發(fā)送出去,同時(shí)指定返回結(jié)果為“Activity.RESULT_OK”。
? ? ? ? 而這里的mSentIntent就是在SmsSingleRecipientSender中指定的,我們?cè)賮砘仡櫼韵庐?dāng)時(shí)的狀態(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;?? ????//拆分長(zhǎng)短信?? ????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á)報(bào)告的Intent?? ????????????deliveryIntents.add(PendingIntent.getBroadcast(?? ????????????????????????mContext,?0,?? ????????????????????????new?Intent(?? ????????????????????????????MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,?? ????????????????????????????mUri,?? ????????????????????????????mContext,?? ????????????????????????????MessageStatusReceiver.class),?? ????????????????????????0));?? ????????}?else?{?? ????????????deliveryIntents.add(null);?? ????????}?? ????????//對(duì)于拆分后的短消息,需要在每條信息發(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ā)送對(duì)象是SmsReceiver,內(nèi)容是MESSAGE_SENT_ACTION,而且包含了附加數(shù)據(jù)EXTRA_MESSAGE_SENT_SEND_NEXT=true,并且SmsTracker發(fā)送該Intent時(shí)傳送的結(jié)果是“Activity.RESULT_OK”。
? ? ? ? 由于SmsReceiver會(huì)把所有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);?? }??
? ? ? ? 對(duì)于當(dāng)前的Intent,將會(huì)在handleSmsSent()中處理:
[java]?view plaincopy private?void?handleSmsSent(Intent?intent,?int?error)?{?? ????Uri?uri?=?intent.getData();?? ????mSending?=?false;?? ????//EXTRA_MESSAGE_SENT_SEND_NEXT表示是否是長(zhǎng)短新的最后一條?? ????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,首先會(huì)通過Sms.moveMessageToFolder()操作將發(fā)送成功的短信從"content://sms/queued"隊(duì)列移動(dòng)到"content://sms/sent"隊(duì)列。
? ? ? ? 然后在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())?{?? ????????????????//從隊(duì)列中取出第一個(gè)并發(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();?? ????}?? }??
? ? ? ? 在上面的過程中,檢測(cè)發(fā)送隊(duì)列中是否有未發(fā)送的短信,對(duì)于多收件人的情況,由于我們之前只發(fā)送出去了第一條短信,而且已經(jīng)將已發(fā)送的短信從該隊(duì)列移出,因此此時(shí)的隊(duì)列中只有其他收件人的短信,然后取出其中的一條,再次進(jìn)入發(fā)送通道,接下來的流程和之前的相同。
? ? ? ? 我們從第一條短信發(fā)送完畢后的流程來尋找答案。
? ? ? ? 由于在GsmSMSDispatcher向RILJ發(fā)送消息時(shí)所注冊(cè)的回應(yīng)消息是EVENT_SEND_SMS_COMPLETE,所以當(dāng)短信發(fā)送成功時(shí),就會(huì)收到該消息的回應(yīng)。
? ? ? ? 在SMSDispatcher中對(duì)該回應(yīng)進(jìn)行處理: [java]?view plaincopy
? ? ? ? 而這里的mSentIntent就是在SmsSingleRecipientSender中指定的,我們?cè)賮砘仡櫼韵庐?dāng)時(shí)的狀態(tài): [java]?view plaincopy
? ? ? ? 由于SmsReceiver會(huì)把所有Intent轉(zhuǎn)交給SmsReceiverService處理,我們直接來看SmsReceiverService的處理: [java]?view plaincopy
? ? ? ? 然后在sendFirstQueuedMessage()中繼續(xù)處理: [java]?view plaincopy
? ? ? ? 這就是多收件人的發(fā)送流程。
Source:?http://blog.csdn.net/u010961631/article/details/50272753
總結(jié)
以上是生活随笔為你收集整理的Android短信发送流程之多收件人发送(原)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android短信发送流程之长短信发送(
- 下一篇: ContentProvider源码分析(