Detailed process of Android 2.3 text message

Source: Internet
Author: User

In android, the APP uses SmsManager. java provides a series of methods to send text messages, and there are many types of content to be sent, such as sendTextMessage, sendMultipartTextMessage, and sendDataMessage, in this article, we will take one of them as an example to describe the complete process of sending text messages. If there are any mistakes, please correct them and learn together.

1. starting point: SmsManager. java (frameworks/base/telephony/java/android/telephony/SmsManager. java)

The core code of sendTextMessage is as follows:


View plaincopy to clipboardprint? Public void sendTextMessage (
......
Try {
ISms iccISms = ISms. Stub. asInterface (ServiceManager. getService ("isms "));
If (iccISms! = Null ){
IccISms. sendText (destinationAddress, scAddress, text, sentIntent, deliveryIntent );
}
} Catch (RemoteException ex ){
// Ignore it
}
}
Public void sendTextMessage (
......
Try {
ISms iccISms = ISms. Stub. asInterface (ServiceManager. getService ("isms "));
If (iccISms! = Null ){
IccISms. sendText (destinationAddress, scAddress, text, sentIntent, deliveryIntent );
}
} Catch (RemoteException ex ){
// Ignore it
}
} View plaincopy to clipboardprint? ISms iccISms = ISms. Stub. asInterface (ServiceManager. getService ("isms "));
ISms iccISms = ISms. stub. asInterface (ServiceManager. getService ("isms"); obtains the service through AIDL, and then calls the sendText () method of the service object. Where is the service object?
2. as we know, create a xx in eclipse. after the aidl file is created, the IDE automatically generates a file named xx using related tools. java interface, which has an internal class named Stub. If we create a class and inherit the internal class, we can implement inter-process communication. This is aidl knowledge, this is not detailed here. Let's look down:

According to the aidl implementation process, the service object should inherit ISms. stub, after searching, we found this service class: IccSmsInterfaceManagerProxy. java, so from SmsManager. the sendTextMessage () method calls the sendText () method of the IccSmsInterfaceManagerProxy object.

3. Phase 2: IccSmsInterfaceManagerProxy. java (frameworks/base/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy)

Let's take a look at the core code of the sendText () method of IccSmsInterfaceManagerProxy:

View plaincopy to clipboardprint? Private IccSmsInterfaceManager mIccSmsInterfaceManager;
......
Public void sendText (String destAddr, String scAddr,
String text, PendingIntent sentIntent, PendingIntent deliveryIntent ){
MIccSmsInterfaceManager. sendText (destAddr, scAddr, text, sentIntent, deliveryIntent );
}
Private IccSmsInterfaceManager mIccSmsInterfaceManager;
......
Public void sendText (String destAddr, String scAddr,
String text, PendingIntent sentIntent, PendingIntent deliveryIntent ){
MIccSmsInterfaceManager. sendText (destAddr, scAddr, text, sentIntent, deliveryIntent );
}
Continue to call. In this case, the sendText () method of the IccSmsInterfaceManager object is called. What is IccSmsInterfaceManager ??

4. Stage 3: IccSmsInterfaceManager. java (frameworks/base/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager. java)

The Code shows that IccSmsInterfaceManager is an abstract class that inherits ISms. Stub. The core code is as follows:

View plaincopy to clipboardprint? Protected SMSDispatcher mDispatcher;
Public void sendText (String destAddr, String scAddr,
String text, PendingIntent sentIntent, PendingIntent deliveryIntent ){
MPhone. getContext (). enforceCallingPermission (
"Android. permission. SEND_SMS ",
"Sending SMS message ");
If (Log. isLoggable ("SMS", Log. VERBOSE )){
Log ("sendText: destAddr =" + destAddr + "scAddr =" + scAddr +
"Text = '" + text + "'sentintent =" +
SentIntent + "deliveryIntent =" + deliveryIntent );
}
MDispatcher. sendText (destAddr, scAddr, text, sentIntent, deliveryIntent );
}
Protected SMSDispatcher mDispatcher;
Public void sendText (String destAddr, String scAddr,
String text, PendingIntent sentIntent, PendingIntent deliveryIntent ){
MPhone. getContext (). enforceCallingPermission (
"Android. permission. SEND_SMS ",
"Sending SMS message ");
If (Log. isLoggable ("SMS", Log. VERBOSE )){
Log ("sendText: destAddr =" + destAddr + "scAddr =" + scAddr +
"Text = '" + text + "'sentintent =" +
SentIntent + "deliveryIntent =" + deliveryIntent );
}
MDispatcher. sendText (destAddr, scAddr, text, sentIntent, deliveryIntent );
}
The sendText () method of the IccSmsInterfaceManager object calls the sendText () method of the SMSDispatcher class and continues:
5. Stage 4: SMSDispatcher. java (frameworks/base/telephony/java/com/android/internal/telephony/SMSDispatcher. java)

This class is an abstract class, and its sendText () is not implemented. Its implementation class is GsmSMSDispatcher. java or CdmaSMSDispatcher. java. If we use a GSM network, the sendText () method of the GSM smsdispatcher is called.

6. Stage 5: GsmSMSDispatcher. java (frameworks/base/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher. java)

The core code is as follows:

View plaincopy to clipboardprint? Protected void sendText (String destAddr, String scAddr, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent ){
SmsMessage. SubmitPdu pdu = SmsMessage. getSubmitPdu (
ScAddr, destAddr, text, (deliveryIntent! = Null ));
SendRawPdu (pdu. encodedScAddress, pdu. encodedMessage, sentIntent, deliveryIntent );
}
......
Protected void sendText (String destAddr, String scAddr, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent ){
SmsMessage. SubmitPdu pdu = SmsMessage. getSubmitPdu (
ScAddr, destAddr, text, (deliveryIntent! = Null ));
SendRawPdu (pdu. encodedScAddress, pdu. encodedMessage, sentIntent, deliveryIntent );
}
......

At this point, the word "sendText ()" is gone, and it is replaced by another method name: sendRawPdu (). Tracing this method can find that it is SMSDispatcher. is this class familiar with a java method? Yes. We have already dealt with it in Stage 4! Let's see what its sendRawPdu does: view plaincopy to clipboardprint? Protected void sendRawPdu (byte [] smsc, byte [] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent ){
......
SendSms (tracker );
.....
}
Protected void sendRawPdu (byte [] smsc, byte [] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent ){
......
SendSms (tracker );
.....
} Another new method is sendSms (). The information sent from sendRawPdu () is encapsulated and transmitted to the sendSms () method for processing. in java, this method just declares that its implementation is defined by the sub-class: GsmSMSDispatcher. java is complete. Let's take a look at GsmSMSDispatcher. java.
7. Stage 6: GsmSMSDispatcher. java (frameworks/base/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher. java)

The core code of the GSM smsdispatcher. java sendSms () method is as follows:

View plaincopy to clipboardprint? Protected CommandsInterface mCm;
 
Protected void sendSms (SmsTracker tracker ){
HashMap map = tracker. mData;
 
Byte smsc [] = (byte []) map. get ("smsc ");
Byte pdu [] = (byte []) map. get ("pdu ");
 
Message reply = obtainMessage (EVENT_SEND_SMS_COMPLETE, tracker );
MCm. sendSMS (IccUtils. bytesToHexString (smsc ),
IccUtils. bytesToHexString (pdu), reply );
}
Protected CommandsInterface mCm;

Protected void sendSms (SmsTracker tracker ){
HashMap map = tracker. mData;

Byte smsc [] = (byte []) map. get ("smsc ");
Byte pdu [] = (byte []) map. get ("pdu ");

Message reply = obtainMessage (EVENT_SEND_SMS_COMPLETE, tracker );
MCm. sendSMS (IccUtils. bytesToHexString (smsc ),
IccUtils. bytesToHexString (pdu), reply );
} Not far from success ....
We know that CommandsInterface is a special interface, its RIL. java is closely related. In the code above, sendSms () calls the sendSMS () method of the CommandsInterface object to do things, while CommandsIterface is an interface, therefore, the task had to be completed by its son (in fact, Sun Tzu, RIL's father BaseCommands is the son of CommandsInterface. java.

8. Stage 7: RIL. java (/frameworks/base/telephony/java/com/android/internal/telephony/RIL. java)

As long as you have studied the ril layer, you must be familiar with it, so you can directly look at its sendSMS () method:

View plaincopy to clipboardprint? Public void sendSMS (String smscPDU, String pdu, Message result ){
RILRequest rr
= RILRequest. obtain (RIL_REQUEST_SEND_SMS, result );
 
Rr. mp. writeInt (2 );
Rr. mp. writeString (smscPDU );
Rr. mp. writeString (pdu );
 
If (RILJ_LOGD) riljLog (rr. serialString () + ">" + requestToString (rr. mRequest ));
 
Send (rr );
}
 
// Send (RILRequest rr)
<Pre name = "code" class = "java"> private void
Send (RILRequest rr ){
Message msg;
 
Msg = mSender. obtainMessage (EVENT_SEND, rr );
 
AcquireWakeLock ();
 
Msg. sendToTarget ();
}
Public void sendSMS (String smscPDU, String pdu, Message result ){
RILRequest rr
= RILRequest. obtain (RIL_REQUEST_SEND_SMS, result );

Rr. mp. writeInt (2 );
Rr. mp. writeString (smscPDU );
Rr. mp. writeString (pdu );

If (RILJ_LOGD) riljLog (rr. serialString () + ">" + requestToString (rr. mRequest ));

Send (rr );
}

// Send (RILRequest rr)
<Pre name = "code" class = "java"> private void
Send (RILRequest rr ){
Message msg;

Msg = mSender. obtainMessage (EVENT_SEND, rr );

AcquireWakeLock ();

Msg. sendToTarget ();
}

OK! In the sendSMS () method, we write the uploaded data to Parcel. When a special RILRequest is sent, where is it sent? Next, let's see: view plaincopy to clipboardprint? Public void
HandleMessage (Message msg ){
RILRequest rr = (RILRequest) (msg. obj );
RILRequest req = null;
 
Switch (msg. what ){
Case EVENT_SEND:
Boolean alreadySubtracted = false;
Try {
LocalSocket s;
......
S. getOutputStream (). write (dataLength );
S. getOutputStream (). write (data );
} Catch (IOException ex ){
......
}
Break;
}
}
Public void
HandleMessage (Message msg ){
RILRequest rr = (RILRequest) (msg. obj );
RILRequest req = null;

Switch (msg. what ){
Case EVENT_SEND:
Boolean alreadySubtracted = false;
Try {
LocalSocket s;
......
S. getOutputStream (). write (dataLength );
S. getOutputStream (). write (data );
} Catch (IOException ex ){
......
}
Break;
}
} Key points: LocalSocket, s. getOutputStream (). write (data)
We write text message-related data and special RILRequst objects into the Socket output stream, and then transmit the data to the RIL layer, that is, the underlying layer, then, the RIL layer parses the data transmitted from the Socket to obtain and process the request content. At this point, the Java section of the text message is complete.

The RIL layer will be analyzed later. If there is something wrong with this article, please let me know. Thank you!

Related Article

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.