Android Mms短信的发送流程,短信发送源码解析

  • 发送前的校验

从短信的点击按钮开始着手:

// packages/apps/Mms/src/com/android/mms/ui/ComposeMessageActivity.java
    @Override
    public void onClick(View v) {
        mIsRTL = (v.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
        if ((v == mSendButtonSms || v == mSendButtonMms) && isPreparedForSending()) {
            ... ...
            if (mShowTwoButtons) {
                confirmSendMessageIfNeeded(SubscriptionManager.getSubId(PhoneConstants.SUB1)[0]);
            } else {
                if (mIsRcsEnabled) {
                    if (RcsUtils.isRcsOnline()
                            && ((mWorkingMessage.getCacheRcsMessage() || (!mWorkingMessage
                                    .requiresMms() && mWorkingMessage.hasText())))) {
                        rcsSend();
                    } else {
                        if (mConversation.isGroupChat()) {
                            toast(R.string.rcs_offline_unable_to_send);
                            return;
                        }
                        if (mIsBurnMessage) {
                            toast(R.string.rcs_not_online_can_not_send_burn_message);
                            mIsBurnMessage = false;
                            return;
                        } else {
                            confirmSendMessageIfNeeded();
                        }
                    }
                } else {
                    confirmSendMessageIfNeeded();
                }
            }
        } 
        ... ...
    }

首先判断是否是双卡的情况,双卡的情况下通过SubId来区分哪张卡;单卡则判断是否启用RCS(rcs默认是关闭的,配置开关的路径:/Mms/res/values/config.xml config_rcs_sms_version)没有启用会执行confirmSendMessageIfNeeded对收件人地址信息确认.

private void confirmSendMessageIfNeeded() {
        LogTag.debugD("confirmSendMessageIfNeeded");
        if (mRcsShareVcard) {
            mWorkingMessage.setRcsType(RcsUtils.RCS_MSG_TYPE_VCARD);
            mRcsShareVcard = false;
        }

        int slot = SubscriptionManager.getSlotId(
                SmsManager.getDefault().getDefaultSmsSubscriptionId());
        if ((TelephonyManager.getDefault().isMultiSimEnabled() &&
                isLTEOnlyMode(slot))
                || (!TelephonyManager.getDefault().isMultiSimEnabled()
                        && isLTEOnlyMode())) {
            showDisableLTEOnlyDialog(slot);
            LogTag.debugD("return for disable LTEOnly");
            return;
        }

        boolean isMms = mWorkingMessage.requiresMms();
        int defaultSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
        if (!isRecipientsEditorVisible()) {
            if (TelephonyManager.getDefault().isMultiSimEnabled()) {
                if ((TelephonyManager.getDefault().getPhoneCount()) > 1 &&
                        MessageUtils.isMsimIccCardActive()) {
                    if(SmsManager.getDefault().isSMSPromptEnabled()) {
                        launchMsimDialog(true, isMms);
                    } else {
                        sendMsimMessageNotPrompt(true, isMms, defaultSubId);
                    }
                } else {
                    sendMsimMessageNotPrompt(true, isMms, defaultSubId);
                }
            } else if (isMmsWithMobileDataOff(isMms, defaultSubId)) {
                showMobileDataDisabledDialog();
            } else {
                sendMessage(true);
            }
            return;
        }
        // 判断收件人地址是否有效
        if (mRecipientsEditor.hasInvalidRecipient(isMms)) {
            showInvalidRecipientDialog();
        } else if (TelephonyManager.getDefault().isMultiSimEnabled()) { // 判断是否是双卡的情况
            if ((TelephonyManager.getDefault().getPhoneCount()) > 1 &&
                    MessageUtils.isMsimIccCardActive()) {
                if(SmsManager.getDefault().isSMSPromptEnabled()) {
                    launchMsimDialog(true, isMms);
                } else {
                    sendMsimMessageNotPrompt(true, isMms, defaultSubId);
                }
            } else {
                sendMsimMessageNotPrompt(true, isMms, defaultSubId);
            }
        } else if (isMmsWithMobileDataOff(isMms, defaultSubId)) {   // 判断是否是彩信,并且数据流量是否打开
            showMobileDataDisabledDialog(defaultSubId);
        } else {
            if (!TextUtils.isEmpty(getString(R.string.mms_recipient_Limit))
                    && isMms
                    && checkForMmsRecipients(getString(R.string.mms_recipient_Limit), true)) {
                return;
            }
            //获取收件人地址,发送
            // The recipients editor is still open. Make sure we use what's showing there
            // as the destination.
            ContactList contacts = mRecipientsEditor.constructContactsFromInput(false);
            mDebugRecipients = contacts.serialize();
            sendMessage(true);
        }
    }

这里是对收件人地址检测等一些状态判断,最后通过sendMessage()继续发送逻辑.

private void sendMessage(boolean bCheckEcmMode) {
        LogTag.debugD("sendMessage true");
        if (mIsRcsEnabled && hasConvertRcsAttachmentToMmsAndSent()) {
            return;
        }
        // Check message size, if >= max message size, do not send message.
        if(checkMessageSizeExceeded()){
            LogTag.debugD("MessageSizeExceeded");
            return;
        }
        // 检查当前是否是ECM模式
        if (bCheckEcmMode) {
            // TODO: expose this in telephony layer for SDK build
            String inEcm = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE);
            if (Boolean.parseBoolean(inEcm)) {
                try {
                    startActivityForResult(
                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null),
                            REQUEST_CODE_ECM_EXIT_DIALOG);
                    return;
                } catch (ActivityNotFoundException e) {
                    // continue to send message
                    Log.e(TAG, "Cannot find EmergencyCallbackModeExitDialog", e);
                }
            }
        }

        // Make the recipients editor lost focus, recipients editor will shrink
        // and filter useless char in recipients to avoid send sms failed.
        if (isRecipientsEditorVisible()
                && mRecipientsEditor.isFocused()
                && !mWorkingMessage.requiresMms()) {
            mTextEditor.requestFocus();
        }
        // 判断是否有短信正在发送
        if (!mSendingMessage) {
            if (LogTag.SEVERE_WARNING) {
                String sendingRecipients = mConversation.getRecipients().serialize();
                if (!sendingRecipients.equals(mDebugRecipients)) {
                    String workingRecipients = mWorkingMessage.getWorkingRecipients();
                    if (workingRecipients != null && !mDebugRecipients.equals(workingRecipients)) {
                        LogTag.warnPossibleRecipientMismatch("ComposeMessageActivity.sendMessage" +
                                " recipients in window: \"" +
                                mDebugRecipients + "\" differ from recipients from conv: \"" +
                                sendingRecipients + "\" and working recipients: " +
                                workingRecipients, this);
                    }
                }
                sanityCheckConversation();
            }
            // send can change the recipients. Make sure we remove the listeners first and then add
            // them back once the recipient list has settled.
            removeRecipientsListeners();

            // 判断是否为多个联系人,然后进入WorkingMessage执行发送
            if (mWorkingMessage.getResendMultiRecipients()) {
                // If resend sms recipient is more than one, use mResendSmsRecipient
                LogTag.debugD("mWorkingMessage send mResendSmsRecipient=" + mResendSmsRecipient);
                mWorkingMessage.send(mResendSmsRecipient);
            } else {
                LogTag.debugD("mWorkingMessage send mDebugRecipients=" + mDebugRecipients);
                mWorkingMessage.send(mDebugRecipients);
            }

            mSentMessage = true;
            mSendingMessage = true;
            addRecipientsListeners();

            mScrollOnSend = true;   // in the next onQueryComplete, scroll the list to the end.
        }
        // But bail out if we are supposed to exit after the message is sent.
        if (mSendDiscreetMode || MessageUtils.isMailboxMode()) {
            finish();
        }
    }

WorkingMessage包含所有用户编辑短信相关的状态,这里判断如果没有短信正在发送,则通过WorkingMessage发送短信.

/**
     * Send this message over the network.  Will call back with onMessageSent() once
     * it has been dispatched to the telephony stack.  This WorkingMessage object is
     * no longer useful after this method has been called.
     *
     * @throws ContentRestrictionException if sending an MMS and uaProfUrl is not defined
     * in mms_config.xml.
     */
    public void send(final String recipientsInUI) {
        long origThreadId = mConversation.getThreadId();

        LogTag.debugD("send origThreadId: " + origThreadId);

        removeSubjectIfEmpty(true /* notify */);

        // Get ready to write to disk.
        prepareForSave(true /* notify */);

        // Make sure the mConversation has Recipients
        checkConversationHasRecipients(recipientsInUI);

        // We need the recipient list for both SMS and MMS.
        final Conversation conv = mConversation;
        String msgTxt = mText.toString();
        if (MmsConfig.isRcsEnabled() && shouldSendMessageWithRcsPolicy()) {
            sendRcsMessage(recipientsInUI);
            return;
        }
        if (requiresMms() || addressContainsEmailToMms(conv, msgTxt)) {     // 发送彩信
            // uaProfUrl setting in mms_config.xml must be present to send an MMS.
            // However, SMS service will still work in the absence of a uaProfUrl address.
            if (MmsConfig.getUaProfUrl() == null) {
                String err = "WorkingMessage.send MMS sending failure. mms_config.xml is " +
                        "missing uaProfUrl setting.  uaProfUrl is required for MMS service, " +
                        "but can be absent for SMS.";
                RuntimeException ex = new NullPointerException(err);
                Log.e(TAG, err, ex);
                // now, let's just crash.
                throw ex;
            }

            // Make local copies of the bits we need for sending a message,
            // because we will be doing it off of the main thread, which will
            // immediately continue on to resetting some of this state.
          
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这是一个自己开发的Android 直接发送短信方法附上代码,Android短信功能,包括了对内容合法性的验证,发送完成弹出提示。自己开发的直接发送短信的方法:   private void sendSMS(String telNo,String smsStr,View v){    PendingIntent pi=    PendingIntent.getActivity(this, 0, new Intent(this,Sample_11_1.class), 0);    SmsManager sms=SmsManager.getDefault();    sms.sendTextMessage(telNo, null, smsStr, pi, null);    //短信发送成功给予提示    Toast.makeText(    Sample_11_1.this, //上下文    "恭喜你,短信发送成功!", //提示内容    5000 //信息显示时间    ).show();    v.setEnabled(true);//短信发送完成后恢复发送按钮的可用状态   }   对手机号码和短信内容的验证部分:   //获取输入的电话号码   EditText etTel=(EditText)findViewById(R.id.EditText02);   String telStr=etTel.getText().toString();   //获取输入的短信内容   EditText etSms=(EditText)findViewById(R.id.EditText01);   String smsStr=etSms.getText().toString();   //判断号码字符串是否合法   if(PhoneNumberUtils.isGlobalPhoneNumber(telStr)){//合法则发送短信    v.setEnabled(false);//短信发送完成前将发送按钮设置为不可用    sendSMS(telStr,smsStr,v);   }   else{//不合法则提示    Toast.makeText(    Sample_11_1.this, //上下文    "电话号码不符合格式!!!", //提示内容    5000//信息显示时间    ).show();   }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值