现在的位置: 首页 > 综合 > 正文

android的短信发送全过程源代码分析

2013年09月19日 ⁄ 综合 ⁄ 共 9797字 ⁄ 字号 评论关闭

首先调用 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      暂时没怎么看

抱歉!评论已关闭.