首先调用 mWorkingMessage.send(); 发送短信

mWorkingMessage.send(); 不用猜测他是什么你就当作是Button的OnClick把

mWorkingMessage.send(){
        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
            LogTag.debug("send");
        }

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

// We need the recipient list for both SMS and MMS.
        final Conversation conv = mConversation;
        String msgTxt = mText.toString();

if (requiresMms() || addressContainsEmailToMms(conv, msgTxt)) {
            // 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.
        //使我们的比特的信息需要发送一个本地副本,
            //因为我们将做它关闭了主线程,这将
            //立即继续以这种状态重置一些
            final Uri mmsUri = mMessageUri;
            final PduPersister persister = PduPersister.getPduPersister(mContext);

final SlideshowModel slideshow = mSlideshow;
            final SendReq sendReq = makeSendReq(conv, mSubject);

// Make sure the text in slide 0 is no longer holding onto a reference to the text
            // in the message text box.
            slideshow.prepareForSend();

// Do the dirty work of sending the message off of the main UI thread.
            new Thread(new Runnable() {
                public void run() {
                    sendMmsWorker(conv, mmsUri, persister, slideshow, sendReq);
                }
            }).start();
        } else {
            // Same rules apply as above.
            final String msgText = mText.toString();
            new Thread(new Runnable() {
                public void run() {
                    sendSmsWorker(conv, msgText); //抓住这点继续追查
                }
            }).start();
        }

// update the Recipient cache with the new to address, if it's different更新了新的收件人地址缓存,如果它的不同
        RecipientIdCache.updateNumbers(conv.getThreadId(), conv.getRecipients());

// Mark the message as discarded because it is "off the market" after being sent.
        mDiscarded = true;
    }

//-------------------------------------------------------------------------------------------------------------------

sendSmsWorker(conv, msgText){

mStatusListener.onPreMessageSent();
        // Make sure we are still using the correct thread ID for our
        // recipient set.
        long threadId = conv.ensureThreadId();
        String[] dests = conv.getRecipients().getNumbers(); //获取收件人的号码

try {
        MessageSender sender = new SmsMessageSender(mContext, dests, msgText, threadId);//构造一个MessageSender 
            sender.sendMessage(threadId); //继续追查数据是怎么发送的

// Make sure this thread isn't over the limits in message count
            Recycler.getSmsRecycler().deleteOldMessagesByThreadId(mContext, threadId);
       } catch (Exception e) {
            Log.e(TAG, "Failed to send SMS message, threadId=" + threadId, e);
        }

mStatusListener.onMessageSent();

//一个默认的构造函数 没有什么特别的地方

public SmsMessageSender(Context context, String[] dests, String msgText, long threadId) {
        mContext = context;
        mMessageText = msgText;
        mNumberOfDests = dests.length;
        mDests = new String[mNumberOfDests];
        System.arraycopy(dests, 0, mDests, 0, mNumberOfDests);
        mTimestamp = System.currentTimeMillis();
        mThreadId = threadId;
        mServiceCenter = getOutgoingServiceCenter(mThreadId);
    }

//-----------------------------------------------------------------------------

sender.sendMessage(threadId){
        if ((mMessageText == null) || (mNumberOfDests == 0)) {
            // Don't try to send an empty message.
            throw new MmsException("Null message body or dest.");
        }

SmsManager smsManager = SmsManager.getDefault();
//群体发送短信
        for (int i = 0; i < mNumberOfDests; i++) {
            ArrayList<String> messages = null; //将要发送的短信
            if ((MmsConfig.getEmailGateway() != null) &&
                    (Mms.isEmailAddress(mDests[i]) || MessageUtils.isAlias(mDests[i]))) {
                String msgText;
                msgText = mDests[i] + " " + mMessageText; //对消息组装   我:你好
                mDests[i] = MmsConfig.getEmailGateway();
                messages = smsManager.divideMessage(msgText);
            } else {
               messages = smsManager.divideMessage(mMessageText);
            }
            int messageCount = messages.size();//短信条数

if (messageCount == 0) {
                // Don't try to send an empty message.
                throw new MmsException("SmsMessageSender.sendMessage: divideMessage returned " +
                        "empty messages. Original message is \"" + mMessageText + "\"");
            }

ArrayList<PendingIntent> deliveryIntents =
                    new ArrayList<PendingIntent>(messageCount);
            ArrayList<PendingIntent> sentIntents =
                    new ArrayList<PendingIntent>(messageCount);
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
            boolean requestDeliveryReport = prefs.getBoolean(
                    MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE,
                    DEFAULT_DELIVERY_REPORT_MODE);
            Uri uri = null;
            try {
                uri = Sms.Outbox.addMessage(mContext.getContentResolver(), mDests[i],
                            mMessageText, null, mTimestamp, requestDeliveryReport, mThreadId); //将要发送的短信添加到数据库中
            } catch (SQLiteException e) {
                SqliteWrapper.checkSQLiteException(mContext, e);
            }

for (int j = 0; j < messageCount; j++) {
                if (requestDeliveryReport) {
                    // TODO: Fix: It should not be necessary to
                    // specify the class in this intent. Doing that
                    // unnecessarily limits customizability.
                    deliveryIntents.add(PendingIntent.getBroadcast(
                            mContext, 0,
                            new Intent(
                                    MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,
                                    uri,
                                    mContext,
                                    MessageStatusReceiver.class),
                            0));
                }
                sentIntents.add(PendingIntent.getBroadcast(
                        mContext, 0,
                        new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,
                                uri,
                                mContext,
                                SmsReceiver.class),
                        0));
            }

if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
                log("sendMessage: address[" + i + "]=" + mDests[i] + ", threadId=" + mThreadId +
                        ", uri=" + uri + ", msgs.count=" + messageCount);
            }

try {
                smsManager.sendMultipartTextMessage( //该是核心发送模块了吧 结果失望了                  
                        mDests[i], mServiceCenter, messages, sentIntents,
                        deliveryIntents);
            } catch (Exception ex) {
                throw new MmsException("SmsMessageSender.sendMessage: caught " + ex +
                        " from SmsManager.sendMultipartTextMessage()");
            }
        }
        return false;

}

//-----------------------------------------------------------------

smsManager.sendMultipartTextMessage(                   
                        mDests[i], mServiceCenter, messages, sentIntents,
                        deliveryIntents){
   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 = ISms.Stub.asInterface(ServiceManager.getService("isms"));
                if (iccISms != null) {
                    iccISms.sendMultipartText(destinationAddress, scAddress, parts,
                            sentIntents, deliveryIntents);
                }
            } catch (RemoteException ex) {
                // ignore it
            }
        } 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); //继续追查ing
        }

}

//------------------------------------------------------------------

sendTextMessage(destinationAddress, scAddress, parts.get(0),
                    sentIntent, deliveryIntent){

String destinationAddress, String scAddress, String text,
            PendingIntent sentIntent, PendingIntent deliveryIntent) {
        if (TextUtils.isEmpty(destinationAddress)) {
            throw new IllegalArgumentException("Invalid destinationAddress");
        }

if (TextUtils.isEmpty(text)) {
            throw new IllegalArgumentException("Invalid message body");
        }

try {
            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); //获得分布式通知服务
            if (iccISms != null) {
                iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); //终于到了核心发送模块
            }
        } catch (RemoteException ex) {
            // ignore it
        }

}

//--------------------------------------------------------------------------------------------

结论google的短信发送过程结构比较合理但是过于复杂

对于短信的发送 核心部分就是

ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms")); //获得分布式通知服务
            if (iccISms != null) {
                iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); //终于到了核心发送模块
其中
ServiceManager.getService("isms")这个我们不必继续查了知道他就是通知底层(C++)我要获得一个ISMS服务的接口规范

然后调用.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent); 将信息发布出去

destinationAddress    接收者的地址 手机号码

scAddress         暂时没深入关注 猜测可能是中心号

text                  不说了

sentIntent   ,deliveryIntent      暂时没怎么看

android的短信发送全过程源代码分析相关推荐

  1. Android Sms短信发送

    界面布局: 具体代码: private void sendSms() {// 获取电话号码和短信内容String number = number1.getText().toString();Strin ...

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

    从前面< Android短信发送流程之普通短信发送 >流程看到,长短信与普通短信的流程从SmsManager的sendMultipartTextMessage()方法开始区分,现在我们来看 ...

  3. Android短信发送流程之普通短信发送(原)

    我们先来看最简单的流程入手分析,即收件人只有一个,而且不是长短信的情况. 一.地址有效性检测 当点击发送按钮时,触发onClick事件: [java] view plaincopy @ComposeM ...

  4. Android6.0的SMS(短信)源码分析--短信发送

    1     SMS发送流程 1.1   SmsManager Android发送短信的接口可以认为是SmsManager,当然并不是所有的App都可以发送短信的,必须配置相关的权限.App中可以通过S ...

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

    发送前的校验 从短信的点击按钮开始着手: // packages/apps/Mms/src/com/android/mms/ui/ComposeMessageActivity.java@Overrid ...

  6. Android项目实践——短信发送接口的封装与设计

    版权声明:本文为博主原创文章,未经博主允许不得转载. 系列教程:Android开发之从零开始系列 大家要是看到有错误的地方或者有啥好的建议,欢迎留言评论 前言:前一段时间公司服务端开发人手不足,而项目 ...

  7. 一枚Android 短信小偷 病毒的分析

    一.样本简介 样本来自于吾爱破解论坛链接地址为http://www.52pojie.cn/thread-410238-1-1.html,样本不是很复杂有空就分析了一下.Android病毒样本还是很有意 ...

  8. android 11.0屏蔽短信功能(短信发送开关)

    1.概述 11.0定制化开发中,需要去掉短信发送功能,这就要从发送短信的流程中来分析了,从流程中了解是如何发送短信的,然后从短信的发送部分,根据系统属性来决定是否继续走完发送短信的流程 2.屏蔽短信功 ...

  9. Android 12.0 屏蔽短信功能(短信发送开关)

    1.概述 在12.0定制化开发中,在一些wifi产品中,需要去掉短信发送功能,这就要从发送短信的流程中来分析了,从流程中了解是如何发送短信的,然后从短信的发送部分,根据系统属性来决定是否继续走完发送短 ...

最新文章

  1. IPsec ××× 配置實例
  2. es6箭头函数this问题
  3. qt creator:一款能够在windows/linux/mac系统上开发c程序的IDE
  4. ssm三大框架工作原理_蒸发器最常见的三大工作原理
  5. php memcache可存,php使用memcache共享存储session(二)
  6. mysql_sed_使用sed提取mysql备份的一行部分
  7. Java命令行界面(第27部分):cli-parser
  8. Missing iOS Distribution signing identity问题解决
  9. Linux 进程状态 说明
  10. Google工程师多图详解Android系统架构
  11. idea 常用配置和快捷键
  12. 结构力学求解器_结构力学学好这些内容对施工很关键,你都学懂了吗?
  13. 解剖SQLSERVER 第九篇 OrcaMDF现在能通过系统DMVs显示元数据(译)
  14. 第四章 类中数据的共享和保护
  15. 计算机专业毕业设计题目大全(各种类型系统设计想法汇总)
  16. 『NLP学习笔记』AllenNLP的注册机制
  17. 论文中MathType公式居中,编号右对齐
  18. 华为无线ensp跨ac三层漫游
  19. 【开发模板】Vue和SpringBoot的前后端分离开发模板
  20. Python学习——语法错误与异常

热门文章

  1. 隐私计算秘密学-秘密分享
  2. 申请开通自媒体账号的署名文章
  3. Tensorflow 2.* 网络训练(二) fit(x, y, batch_size, epochs, verbose, validation_split, initial_epoch... )
  4. 【杂七杂八的笔记】2019CVPR论文快读
  5. 教你分析快递揽收后,第二条物流是否超过12小时
  6. Linux驱动学习--V4L2框架
  7. java.lang.NoClassDefFoundError: com/huaban/analysis/jieba/JiebaSegmenter
  8. exadata的infiniband交换机的ilom
  9. DVWA windows提权
  10. 多域名同一空间的处理实例附(ASP代码)