SMS sending-SMS sending process-Application Layer

Source: Internet
Author: User
Application Layer Analysis of SMS sending Process 1. involved classes

com.android.mms.ui.ComposeMessageActivitycom.android.mms.data.WorkingMessagecom.android.mms.transaction.MessageSendercom.android.mms.transaction.SmsMessageSendercom.android.mms.transaction.SmsSingleRecipientSendercom.android.mms.transaction.SmsReceiverServicecom.android.mms.transaction.SmsReceiver
2. Time Sequence Diagram Note: From the UI interface to the call of the middle layer smsmanger method to send text messages, the approximate time sequence is like this. The reference code is Android 2.3. 3. Process Analysis 3.1 composemessageactivity work

This class is the UI for editing text messages and interacting with users, as shown in


After editing, you can click the send button to send the text message content. Clicking sendbutton triggers the listener corresponding to the button. Because composemessageactivity implements the onclicklistener interface, therefore, The onclick method is finally called.

1) onclick Analysis

This method does two things:

The first is to call the ispreparedforsending method to determine whether the current text message is to be sent, based on whether the recipient of the text message exceeds the allowed upper limit, whether there are recipients, and whether the text message contains content, attachments, themes, and so on, users are not allowed to send a text message without any content.

Second, the above check starts the sending process by calling the confirmsendmessageifneeded method. Of course, this method will not be successfully sent if it is called. This method will also perform a series of checks until it meets the requirements.

2) confirmsendmessageifneeded Analysis

Shows the logical call of this method:

3) The sendmessage method analysis shows that we have to go to sendmessage. Let's take a look at what work this method has done. By viewing the code, we can find that the core task is to send the text message to workingmessage and mworkingmessage. Send (mdebugrecipients). Other tasks are only for some auxiliary operations. Conclusion: The work of sending text messages till now is handed over to workingmessage, so the main task of composemessageactivity is to process dual-card.

3.2 simple analysis of workingmessage

1) Send () Analysis

This method performs five tasks: first, check whether the receiver list is empty, so I will not perform specific analysis here. The second is to convert the text message content from 8 bytes to 7 bytes. The third is to determine whether or not the current message is sent. Currently, the text message is sent, so the MMS sending process will not be followed. 4. Add the text message signature to the text message content. 5. Call the presendsmsworker () method. 2) presendsmsworker: reset the interface, clear all the components on the interface, call the sendsmsworker method, and delete the draft. 3) The work done by sendsmsworker () calls the sendmessage () method of smsmessagesender 3.3 smsmessagesender Analysis 1) sendmessage ()

This method will call the queuemessage () method to throw the task to process the sent task.

2) queuemessage () has two responsibilities: one is to save the messages to be sent to the database;
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);        boolean requestDeliveryReport = prefs.getBoolean(                MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE,                DEFAULT_DELIVERY_REPORT_MODE);        for (int i = 0; i < mNumberOfDests; i++) {            try {                log("updating Database with sub = " + mSubscription);                Sms.addMessageToUri(mContext.getContentResolver(),                        Uri.parse("content://sms/queued"), mDests[i],                        mMessageText, null, mTimestamp,                        true /* read */,                        requestDeliveryReport,                        mThreadId, mSubscription);            } catch (SQLiteException e) {                SqliteWrapper.checkSQLiteException(mContext, e);            }        }

Second, transfer the task to another person, except that it is broadcast;

     // Notify the SmsReceiverService to send the message out        Intent intent = new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, null, mContext, SmsReceiver.class);intent.putExtra(SUBSCRIPTION, mSubscription);        mContext.sendBroadcast(intent);

Summary: this class has done a very important task: Saving the text message to be sent to the database, and then sending a broadcast notification smsreceiver;
3.4 smsreceiver to smsreceiverservice

In fact, the smsreceiver guy is not an officer either. He just handed it over to the smsreceiverservice immediately after getting it. "I don't care about this. I am a courier.", the role of smsreceiver is like this. You can refer to the time sequence diagram for calling methods;

3.5 smsreceiverservice Analysis

After talking about it for a long time, I finally got to work. Since it is a service, of course it will go through its own declared periodic function, first oncrate. This method has been initialized in recent years, and then onstartcommand (), this method does not do anything. It only sends messages to servicehandler. It seems that people have made great efforts.

1) servicehandler processes send requests
  @Override        public void handleMessage(Message msg) {            int serviceId = msg.arg1;            Intent intent = (Intent)msg.obj;            if (intent != null) {                String action = intent.getAction();                int error = intent.getIntExtra("errorCode", 0);              if (SMS_RECEIVED_ACTION.equals(action)) {                    handleSmsReceived(intent, error);                } else if (SMS_CB_RECEIVED_ACTION.equals(action)) {                    handleCbSmsReceived(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(intent);                }            }            // NOTE: We MUST not call stopSelf() directly, since we need to            // make sure the wake lock acquired by AlertReceiver is released.            SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId);        }    }

After receiving the message, the handlesendmessage method is used;

2) handlesendmessage () Analysis: 1. Determine whether the dual-card can be used. If the current card is obtained and sendfirstqueuedmessage (INT sub) is called. 2. If the dual-card is not used, directly call the sendfirstqueuedmessage () method. Note: two different methods are called. You can see their parameters, but actually sendfirstqueuedmessage () the function without parameters is implemented by calling sendfirstqueuedmessage (INT sub). It is equivalent to calling sendfirstqueuedmessage (INT sub). 3) sendfirstqueuedmessage (INT sub) in brief, it first extracts text messages from the database, and then calls the sendmessage () method of smssinglerecipientsender to send the messages. Conclusion: you can find that the message was not sent after half a day. 3.6 smssinglerecipientsender

Sendmessage () Description:

The first is to split the text message content. The second is to save the text message to the outbox database table. The third is to separate the separated text messages and send the fourth is to send the sendmultiparttextmessage () of the smsmanger class called, transfers the specific operation to the intermediate layer. The Code is as follows:
if (mMessageText == null) {            // Don't try to send an empty message, and destination should be just            // one.            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);           // remove spaces from destination number (e.g. "801 555 1212" -> "8015551212")           mDest = mDest.replaceAll(" ", "");        }        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 + "\"");        }        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) {                // 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,                                mUri,                                mContext,                                MessageStatusReceiver.class),                        0));            }            Intent intent  = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,                    mUri,                    mContext,                    SmsReceiver.class);            int requestCode = 0;            if (i == messageCount -1) {                // Changing the requestCode so that a different pending intent                // is created for the last fragment with                // EXTRA_MESSAGE_SENT_SEND_NEXT set to true.                requestCode = 1;                intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT, true);                intent.putExtra(SUBSCRIPTION, mSubscription);            }            sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0));        }        try {            smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents,                       deliveryIntents, mSubscription);        } catch (Exception ex) {            throw new MmsException("SmsMessageSender.sendMessage: caught " + ex +                    " from SmsManager.sendTextMessage()");        }        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {            log("sendMessage: address=" + mDest + ", threadId=" + mThreadId +                    ", uri=" + mUri + ", msgs.count=" + messageCount);        }

4. Summary

 This part mainly analyzes the process of sending short messages, starting from clicking the button on the UI to executing the sending operation on the middle layer. Of course, there are still many unknown points here, I am also trying to improve it.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.