Observe the text message interception of 360 and the text message interception of QQ manager, and find that the installed text message can be intercepted first, and then the broadcast is interrupted. Then no one can get the text message. Here, we can launch a broadcast table for the system, which is discharged in the order of installation at the same level. The current method is to call the framework API at the application layer for control.
In order to better understand the process of receiving text messages from android, I conducted a more in-depth analysis and analyzed the entire process of receiving text messages from RIL's communication architecture. From RIL. java in frameword
The file shows that text messages are sent and received through the explorer and Sender architecture, and text messages are sent mainly through the Sender framework, as shown in the figure below (from the Internet ~) :
Upper-layer functions call Command Interface to send request messages to the sender architecture, where requests are sent to the RILD architecture.
At present, we mainly analyze the channels used to receive text messages. Therefore, sending text messages is just a slight explanation.
The process for receiving a text message is as follows (from sending a message to receiving a message) (the figure below shows the process for uploading a text message from the Internet ~) :
From the block on the right (combined with the Code), we can see that the message is received from ril. the cpp file uses socket and RIL. java socket communication when ril. after receiving the text message, cpp sends the byte stream to the upper-layer RIL through socket. java, while in RIL. java has a worker er architecture (which is mainly a thread) that is constantly monitored,
Receiver Architecture code:
Class RILReceiver implements Runnable {
Byte [] buffer;
RILReceiver (){
Buffer = new byte [RIL_MAX_COMMAND_BYTES];
}
Public void
Run (){
Int retryCount = 0;
Try {
For (;;){
LocalSocket s = null;
LocalSocketAddress l;
Try {
S = new LocalSocket ();
L = new LocalSocketAddress (SOCKET_NAME_RIL,
LocalSocketAddress. Namespace. RESERVED );
S. connect (l );
} Catch (ioexception ex ){
Try {
If (s! = NULL ){
S. Close ();
}
} Catch (ioexception ex2 ){
// Ignore failure to close after failure to connect
}
// Don't print an error message after the first time
// Or after the 8th time
If (retryCount = 8 ){
Log. e (LOG_TAG,
"Couldn't find '" + SOCKET_NAME_RIL
+ "'Socket after" + retryCount
+ "Times, continuing to retry silently ");
} Else if (retryCount> 0 & retryCount <8 ){
Log. I (LOG_TAG,
"Couldn't find '" + SOCKET_NAME_RIL
+ "'Socket; retrying after timeout ");
}
Try {
Thread. Sleep (socket_open_retry_millis );
} Catch (interruptedexception ER ){
}
Retrycount ++;
Continue;
}
Retrycount = 0;
Msocket = s;
Log. I (LOG_TAG, "Connected to '" + SOCKET_NAME_RIL
+ "'Socket ");
Int length = 0;
Try {
InputStream is = mSocket. getInputStream ();
For (;;){
Parcel P;
Length = readrilmessage (is, buffer );
If (length <0 ){
// End-of-stream reached
Break;
}
P = Parcel. obtain ();
P. unmarshall (buffer, 0, length );
P. setDataPosition (0 );
// Log. v (LOG_TAG, "Read packet:" + length +
// "Bytes ");
ProcessResponse (p );
P. recycle ();
}
} Catch (Java. Io. ioexception ex ){
Log. I (log_tag, "'" + socket_name_ril
+ "'Socket closed ",
Ex );
} Catch (throwable TR ){
Log. e (LOG_TAG, "Uncaught exception read length ="
+ Length +
"Exception:" + tr. toString ());
}
Log. I (LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
+ "'Socket ");
Setradiostate (radiostate. radio_unavailable );
Try {
Msocket. Close ();
} Catch (ioexception ex ){
}
Msocket = NULL;
Rilrequest. resetserial ();
// Clear request list on close
Synchronized (mrequestslist ){
For (INT I = 0, SZ = mrequestslist. Size (); I <SZ; I ++ ){
Rilrequest RR = mrequestslist. Get (I );
Rr. onerror (radio_not_available, null );
Rr. Release ();
}
Mrequestslist. Clear ();
}
}
} Catch (throwable TR ){
Log. E (log_tag, "uncaught exception", TR );
}
}
}
Therefore, we can see from the code that after obtaining the short message, it goes through a series of analysis and then submits it to processResponse (p). There are two kinds of response in the process, one is to actively report, for example, the network status, text message, and incoming call do not need to go through the request. The unsolicited term is used to describe it. The other is the real response, that is, the command response is described with solicited. Then, the message is received by unsolicited. When you jump to the processUnsolicited (Parcel p) method, you can find that the following method will continue to be triggered: mSMSRegistrant. notifyRegistrant (new AsyncResult (null, sms, null); traces the creation of the method object, and finds that the source of handler setting for this method is in the SMSDispatcher class.
This class has done an important thing: Set the handler processing method for the Command Interface, that is, when the message is received, mSMSRegistrant is triggered. notifyRegistrant (new AsyncResult (null, sms, null); method, callback call the previously passed handler, and then process the text message in the handler.
MCm. setOnNewSMS (this, EVENT_NEW_SMS, null );
MCm. setOnSmsStatus (this, EVENT_NEW_SMS_STATUS_REPORT, null );
MCm. setOnIccSmsFull (this, EVENT_ICC_FULL, null );
MCm. registerForOn (this, EVENT_RADIO_ON, null );
Handler processes received SMS messages:
@ Override
Public void handleMessage (Message msg ){
AsyncResult ar;
Switch (msg. what ){
Case EVENT_NEW_SMS:
// A new SMS has been encrypted ed by the device
If (Config. LOGD ){
Log. d (TAG, "New SMS Message Received ed ");
}
SmsMessage sms;
Ar = (AsyncResult) msg. obj;
If (AR. Exception! = NULL ){
Log. E (TAG, "Exception Processing incoming SMS. Exception :"
+ Ar. Exception );
Return;
}
SMS = (smsmessage) Ar. result;
Try {
Int result = dispatchMessage (sms. mwrappedsmessage );
If (result! = Activity. RESULT_ OK ){
// RESULT_ OK means that message was broadcast for app (s)
// Handle.
// Any other result, we shoshould ack here.
Boolean handled = (result = Intents. RESULT_SMS_HANDLED );
Notifyandacknowledgelastincomingsms (handled, result, null );
}
} Catch (runtimeexception ex ){
Log. E (TAG, "exception dispatching message", ex );
Yyandacknowledgelastincomingsms (false,
Intents. result_sms_generic_error, null );
}
Break;
}
}
Int result = dispatchMessage (sms. mwrappedsmessage); this section is processed by the dispatchMessage method of the subclass (GsmSMSDispatcher. After a series of judgment and processing, the common text message will be handed over to dispatchPdus (pdus.
Protected void dispatchPdus (byte [] [] pdus ){
Intent intent = new Intent (Intents. SMS_RECEIVED_ACTION );
Intent. putExtra ("pdus", pdus );
Dispatch (intent, "android. permission. RECEIVE_SMS ");
}
Void dispatch (Intent intent, String permission ){
// Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
// Receivers time to take their own wake locks.
MWakeLock. acquire (WAKE_LOCK_TIMEOUT );
Mcontext. sendorderedbroadcast (intent, permission, mresultreceiver,
This, activity. result_ OK, null, null );
}
Finally, we can see that this method broadcasts messages in sequence (the action is sms_received_action). mresultreceiver is called no matter whether the broadcast is interrupted or not, the read or unread status is reported to the other party. If the SMS broadcast is not terminated, the following process is: The privilegedsmsreceiver class receives the Android. provider. telephony. sms_received request and then calls intent. setclass (context, smsreceiverservice.Class); Start the smsreceiverservice service class to process the text message and save the text message.
References:
Http://newfaction.net/2011/03/15/android-2-2-ril-java-part-of-the-code-profile.html
Http://blog.csdn.net/maxleng/article/details/5593759
Http://www.360doc.com/content/10/0625/11/496343_35127382.shtml