android接收短信——framework处理流程(android 5.1)
modem层不懂,所以直接从RIL.java开始。以电信卡接收短信为例
modem通知RIL.java中的 RILReceiver处理接收信息
class RILReceiver implements Runnable {
byte[] buffer;
RILReceiver() {
buffer = new byte[RIL_MAX_COMMAND_BYTES];
}
@Override
public void
run() {
......
//建立socked连接,读取数据
processResponse(p);
......
}
}
private void
processResponse (Parcel p) {
int type; type = p.readInt(); if (type == RESPONSE_UNSOLICITED) {
processUnsolicited (p); //接收短息会进入这里
} else if (type == RESPONSE_SOLICITED) {
RILRequest rr = processSolicited (p);
if (rr != null) {
rr.release();
decrementWakeLock();
}
}
}
processUnsolicited(Parcel p)方法中,罗列了各种类型的信息,
processUnsolicited (Parcel p) {
int response;
Object ret;
response = p.readInt(); try {switch(response) {
/*
cat libs/telephony/ril_unsol_commands.h \
| egrep "^ *{RIL_" \
| sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
*/
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break;
case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break;
case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_SIM_REFRESH: ret = responseSimRefresh(p); break;
case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break;
case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_CELL_INFO_LIST: ret = responseCellInfoList(p); break;
case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_SRVCC_STATE_NOTIFY: ret = responseInts(p); break;
case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: ret = responseHardwareConfig(p); break;
case RIL_UNSOL_RADIO_CAPABILITY:
ret = responseRadioCapability(p); break;
case RIL_UNSOL_ON_SS: ret = responseSsData(p); break;
case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: ret = responseString(p); break;
case RIL_UNSOL_LCEDATA_RECV: ret = responseLceData(p); break;
电信卡接收信息,是 RIL_UNSOL_RESPONSE_CDMA_NEW_SMS
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
if (RILJ_LOGD) unsljLog(response); SmsMessage sms = (SmsMessage) ret; if (mCdmaSmsRegistrant != null) {
mCdmaSmsRegistrant
.notifyRegistrant(new AsyncResult(null, sms, null)); //mCdmaSmsRegistrant 在 CdmaInboundSmsHandler 初始化时创建
}
break;
public void
notifyRegistrant(AsyncResult ar)
{
internalNotifyRegistrant (ar.result, ar.exception);
} /*package*/ void
internalNotifyRegistrant (Object result, Throwable exception)
{
Handler h = getHandler(); if (h == null) {
clear();
} else {
Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj, result, exception); h.sendMessage(msg); //handler来处理接收信息事件
}
}
mCdmaSmsRegistrant.notifyRegistrant(..)就进入状态机(StateMachine)处理了。处理的信息接收的状态机是 InboundSmsHandler extends StateMachine
InboundSmsHandler是抽象类,对于CDMA信息是 CdmaInboundSmsHandler extends InboundSmsHandler, 对于GSM信息是 GsmInboundSmsHandler extends InboundSmsHandler 关于CdmaInboundSmsHandler 状态机是何时启动并初始化的,细节没研究。应该是在手机启动后,一系列系统服务启动时完成的。
看看CdmaInboundSmsHandler 的构造函数
/**
* Create a new inbound SMS handler for CDMA.
*/
private CdmaInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
PhoneBase phone, CdmaSMSDispatcher smsDispatcher) {
super("CdmaInboundSmsHandler", context, storageMonitor, phone,
CellBroadcastHandler.makeCellBroadcastHandler(context, phone));
mSmsDispatcher = smsDispatcher;
mServiceCategoryProgramHandler = CdmaServiceCategoryProgramHandler.makeScpHandler(context,
phone.mCi);
phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null); //这里构造了RIL中需要的 mCdmaSmsRegistrant
}
public void setOnNewCdmaSms(Handler h, int what, Object obj) {
mCdmaSmsRegistrant = new Registrant (h, what, obj);
}
/**
* Wait for state machine to enter startup state. We can't send any messages until then.
*/
public static CdmaInboundSmsHandler makeInboundSmsHandler(Context context,
SmsStorageMonitor storageMonitor, PhoneBase phone, CdmaSMSDispatcher smsDispatcher) {
CdmaInboundSmsHandler handler = new CdmaInboundSmsHandler(context, storageMonitor,
phone, smsDispatcher); //构造CdmaInboudSmsHandler状态机
handler.start(); //启动 state machine
return handler;
}
在CdmaInboudSmsHandler初始化会调用父类InboundSmsHandler的构造函数,会增加各种状态。
protected InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor,
PhoneBase phone, CellBroadcastHandler cellBroadcastHandler) {
super(name);
...... addState(mDefaultState);
addState(mStartupState, mDefaultState);
addState(mIdleState, mDefaultState);
addState(mDeliveringState, mDefaultState);
addState(mWaitingState, mDeliveringState); setInitialState(mStartupState);
if (DBG) log("created InboundSmsHandler");
}
综上,RILReceiver接收信息,进入状态机CdmaInboundSmsHandler处理,具体是父类StateMachine中的Hanler传递消息,并切换各状态(state)处理。
状态: mDefaultState,mStartupState,mIdleState,mDeliveringState,mWaitingState以及默认的QuitSatte, HaltState。
各状态是如何切换处理的? 没搞明白。有待研究。 接收信息最终传递处理在 mDeliveringState中 (代码实现在InboundsSmsHandler.java中)
class DeliveringState extends State {
@Override
public void enter() {
if (DBG) log("entering Delivering state");
}
@Override
public void exit() {
if (DBG) log("leaving Delivering state");
}
@Override
public boolean processMessage(Message msg) {
log("DeliveringState.processMessage:" + msg.what);
switch (msg.what) {
case EVENT_NEW_SMS:
// handle new SMS from RIL
handleNewSms((AsyncResult) msg.obj); //继续处理新接收的信息
sendMessage(EVENT_RETURN_TO_IDLE);
return HANDLED;
void handleNewSms(AsyncResult ar) {
if (ar.exception != null) {
loge("Exception processing incoming SMS: " + ar.exception);
return;
}
int result;
try {
SmsMessage sms = (SmsMessage) ar.result;
result = dispatchMessage(sms.mWrappedSmsMessage); //信息传递处理完成,并返回结果
} catch (RuntimeException ex) {
loge("Exception dispatching message", ex);
result = Intents.RESULT_SMS_GENERIC_ERROR;
}
// RESULT_OK means that the SMS will be acknowledged by special handling,
// e.g. for SMS-PP data download. Any other result, we should ack here.
if (result != Activity.RESULT_OK) { //注意这里的返回结果,一般是 Intents.RESULT_SMS_HANDLED,才可以继续反馈 ack 到 smsc
boolean handled = (result == Intents.RESULT_SMS_HANDLED);
notifyAndAcknowledgeLastIncomingSms(handled, result, null); //这里返回ACK给短信中心(smsc),表示信息已接收。
}
}
void notifyAndAcknowledgeLastIncomingSms(boolean success,
int result, Message response) {
if (!success) {
// broadcast SMS_REJECTED_ACTION intent
Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
intent.putExtra("result", result);
mContext.sendBroadcast(intent, android.Manifest.permission.RECEIVE_SMS);
}
acknowledgeLastIncomingSms(success, result, response);
}
protected abstract void acknowledgeLastIncomingSms(boolean success,
int result, Message response); //具体实现在 CdmaInboundsSmsHandler 或 GsmInboundSmsHandler中
CdmaInboundsSmsHandler中处理acknowledgeLastIncomingSms
@Override
protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
if (isInEmergencyCallMode()) {
return;
} int causeCode = resultToCause(result);
mPhone.mCi.acknowledgeLastIncomingCdmaSms(success, causeCode, response); //这里又回到RIL中处理 if (causeCode == 0) {
mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
}
mLastDispatchedSmsFingerprint = null;
}
RIL中用 RILSender 处理返回ACK,
public void
acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result); rr.mParcel.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
// cause code according to X.S004-550E
rr.mParcel.writeInt(cause); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + success + " " + cause); send(rr);
}
再看看信息传递处理dispatchMessage()
public int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, there was a parsing error.
if (smsb == null) {
loge("dispatchSmsMessage: message is null");
return Intents.RESULT_SMS_GENERIC_ERROR;
}
if (mSmsReceiveDisabled) {
// Device doesn't support receiving SMS,
log("Received short message on device which doesn't support "
+ "receiving SMS. Ignored.");
return Intents.RESULT_SMS_HANDLED;
}
return dispatchMessageRadioSpecific(smsb);
}
protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb);
InboundsSmsHandler中的dispatchMessageRadioSpecific(..)是抽象的,具体处理在CdmaInboundSmsHandler 或 GsmInboundSmsHandler中
然后会将新信息,用广播传递给MMS应用处理。
android接收短信——framework处理流程(android 5.1)的更多相关文章
- Android接收短信
Android收到短信时会广播android.provider.Telephony.SMS_RECEIVED消息,因此只要定义一个Receiver,收听该消息,就能接收短信. <receiver ...
- Android 接收短信
启动程序时启动一个service,在service里注册接收短信的广播,当手机收到短信里,打印出短信内容跟电话号码. package com.lmy.SmsListener; import andro ...
- android拦截短信并屏蔽系统的Notification
拦截短信有几个关键点: 1.android接收短信时是以广播的方式 2.程序只要在自己的Manifest.xml里加有"接收"SMS的权限 <uses-permission ...
- Android短信彩信收发流程(应用层)
下图为ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息发送流程.主要以接收者有效性的确认为主,然后转向sendMessage方法进行发送. ...
- android 发送短信的两种方式,以及接收报告和发送报告
android发送短信,以及接收报告和发送报告 android中发送短信其实有两种方式,这个和打电话类似,大家可以了解一下: 一.调起系统发短信功能 ...
- android基础---->发送和接收短信
收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这项功能,而Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.今天我们开始自己创建一个简单的发送和接收短 ...
- android学习十四(android的接收短信)
收发短信是每一个手机主要的操作,android手机当然也能够接收短信了. android系统提供了一系列的API,使得我们能够在自己的应用程序里接收和发送短信. 事实上接收短信主要是利用我们前面学过的 ...
- Android使用BroadCastRecevier广播实现接收短信,并利用Toast弹出显示内容
在上一篇文章 Android简单实现BroadCastReceiver广播机制 中简单的实现了一个广播机制,这里利用BroadCarstRecevier实现一个接收短信并显示内容的案例,当然至于接收到 ...
- android发送短信验证码并自动获取验证码填充文本框
android注册发送短信验证码并自动获取短信,截取数字验证码填充文本框. 一.接入短信平台 首先需要选择短信平台接入,这里使用的是榛子云短信平台(http://smsow.zhenzikj.com) ...
随机推荐
- sassCore
core文件 setting 负责基础变量的文件,如常用的颜色,字体等变量. css3 负责css3属性前缀的文件.参考了bourbon,然后进行一系列的扩展及优化,以使解析出来的代码更加合理. me ...
- jquery仿淘宝规格颜色选择效果
jquery实现的仿淘宝规格颜色选择效果源代码如下 jquery仿淘宝规格颜色选择效果 -收缩HTML代码 运行代码 [如果运行无效果,请自行将源代码保存为html文件运行] <script t ...
- 初尝 JFinal 项目(二)
这里以Roles角色表修改功能做一个例子 RolesController /** * 角色管理控制类 * @author 御手洗红豆 */public class RolesController ex ...
- python Tornado(招聘的一个比较经常问到的知识)
Tornado既是一个webserver也是一个web框架 这是一个总结的比较详细的内容 http://www.nowamagic.net/academy/detail/1332612 开源中国中的关 ...
- phpMyAdmin登录出错
问题:在网页上登录phpMyAdmin后出错 You don't have permission to access /phpMyAdmin/ on this server. 查询找到解决方法,记录一 ...
- HashTable 简述
1.解释:使用了映射函数,把值映射到对应的位置,key-> address, address是表中的存储位置,不是实际的地址: 2.Hash 函数设计, 分布合理,冲突少,利用率平衡,利用率 ...
- 浅谈WebSocket
WebSocket是H5提出的为了解决客户端和服务器双工通信的方法.在我们使用HTTP协议通信时,客户端主动向服务器发送请求,得到服务器端数据.为了与服务器端数据保持一致,之前常用的有轮询和长轮询两种 ...
- wsimport命令讲解
wsimport是JDK自带的工具,主要功能是根据服务端生成的WSDL文件创建客户端支持代码.生成java客户端代码常使用的命令参数说明: 参数 说明 -p 定义客户端生成类的包名称 -s 指定客户端 ...
- 利用JDK(1.6及以上版本)创建WebService
一.什么是WebService WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络 ...
- Oracle数据访问组件ODAC的安装方法:
Oracle数据访问组件ODAC(Oracle Data Access Components)顾名思义就是用来访问Oracle数据库的小程序.我们可以编程调用这些组件来实现在没有安装Oracle数据库 ...