[转载]android 短信接收流程分析——为更好的拦截短信做准备

[转载]android 短信接收流程分析——为更好的拦截短信做准备 – 没有代码 – 博客园.

观察360的短信拦截和QQ管家的短信拦截,发现先安装的就能先拦截到的短信,然后中断广播,之后谁都不能获取到短信。从这里可以推出系统大概有一个广播表,同等级的按安装先后顺序排放。目前的方法是在应用层调用framework API进行控制的。

为了能更好的了解Android接收短信的流程,我进行了更深入的分析,从RIL的通信架构来分析当接收到短信的整个流程。从frameword里的RIL.java

clip_image002

文件可以看出发送短信和接收短信是通过Receiver和Sender架构,发送短信主要通过Sender框架,主要如下(图是从网上窃滴~):

image

上层函数调用Command Interface将请求消息发送到sender架构,由该架构将请求发送到RILD的架构。

目前主要分析接收短信走过的那些渠道,因此发送短信只是略微的说明一下。

接收短信流程如下(从发送消息到接收消息的处理流程)(图是从网上剽滴~):

clip_image002[6]

从 上图右边那块(结合代码)可以看出短信接收是从ril.cpp文件通过socket与RIL.java的socket交流,当ril.cpp收到短信后处 理完成后会通过socket发送字节流给上层的RIL.java,而在RIL.java中有Receiver架构(该架构主要是一条线程)在不断监听,

Receiver架构代码:

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 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);

}

}

}

因 此从代码可以看出获取到短信消息后经过一系列地分析然后提交给processResponse(p); 方法处理,处理过程中会有两种response,一种是主动上报,比如网络状态,短信,来电等都不需要经过请求,用unsolicited词语专门描述, 另一种才是真正意义上的response,也就是命令的响应用solicited描述。那接收短信就是属于unsolicited,跳到 processUnsolicited (Parcel p)方法,查看该方法可得出会继续触发以下方法mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null)); 追溯该方法对象的创建,最后发现该方法设置handler的源头是在:SMSDispatcher类里

clip_image004

该 类做了一件重要的事:给Command Interface设置handler的处理方法,就是当接收到短信后触发mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));方法,然后回调调用之前传入的handler,接着在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处理接收到的短信消息:

@Override
public void handleMessage(Message msg) {

AsyncResult ar;

switch (msg.what) {

case EVENT_NEW_SMS:

// A new SMS has been received by the device

if (Config.LOGD) {

Log.d(TAG, “New SMS Message Received”);

}

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.mWrappedSmsMessage);

if (result != Activity.RESULT_OK) {

// RESULT_OK means that message was broadcast for app(s) to
// handle.

// Any other result, we should ack here.

boolean handled = (result == Intents.RESULT_SMS_HANDLED);

notifyAndAcknowledgeLastIncomingSms(handled, result, null);

}

} catch (RuntimeException ex) {

Log.e(TAG, “Exception dispatching message”, ex);

notifyAndAcknowledgeLastIncomingSms(false,
Intents.RESULT_SMS_GENERIC_ERROR, null);

}

break;

}

}

int result = dispatchMessage(sms.mWrappedSmsMessage); 该段会通过子类(GsmSMSDispatcher)的dispatchMessage方法处理。经一系列的判断处理最后普通短信将交给 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);

}

最 后,我们可以看出这个方法将短信通过顺序广播播放出去(action是SMS_RECEIVED_ACTION),无论广播是否被中断最后都会调用 mResultReceiver,这里会将已读或未读的状态告诉给对方。如果短信广播中间没有受到終止,那么接下来的流程 是:PrivilegedSmsReceiver类接收到android.provider.Telephony.SMS_RECEIVED的请求然后调 用 intent.setClass(context, SmsReceiverService.class); 启动SmsReceiverService服务类来处理短信并保存短信。

参考文章:

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

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏