Android短信接收过程源码分析.docx
- 文档编号:4882847
- 上传时间:2022-12-11
- 格式:DOCX
- 页数:9
- 大小:130.11KB
Android短信接收过程源码分析.docx
《Android短信接收过程源码分析.docx》由会员分享,可在线阅读,更多相关《Android短信接收过程源码分析.docx(9页珍藏版)》请在冰豆网上搜索。
Android短信接收过程源码分析
Android短信接收过程源码分析(原)
‘
目录(?
)[-]
∙一GsmSMSDispatcher注册监听过程
∙二RILJ通知GsmSMSDispatcher过程
∙三SMSDispatcher把短信通知发送到系统广播的过程
∙四总体流程图
本文主要讨论RILJ接收到一条普通短消息时是如何把它转换成Broadcast发送到系统中的。
一、GsmSMSDispatcher注册监听过程
Framework与应用层中的Phone对象其实就是用GSMPhone对象生成的PhoneProxy对象(CDMA制式不谈)。
可以简单的理解为Phone就是GSMPhone对象。
而GSMPhone又是Framework中与RIL层沟通的对象,因此我们从GSMPhone开始入手分析。
[java]viewplaincopy
∙@GSMPhone.java
∙publicGSMPhone(Contextcontext,CommandsInterfaceci,PhoneNotifiernotifier,booleanunitTestMode){
∙//调用父类PhoneBase的构造函数,在内部实现一下赋值:
phone.mCM=ci=RILJ
∙super(notifier,context,ci,unitTestMode);
∙
∙//初始化GsmSMSDispatcher,用于派发短消息
∙mSMS=newGsmSMSDispatcher(this,mSmsStorageMonitor,mSmsUsageMonitor);
∙}
上面看到,在GSMPhone的构造函数中,创建了GsmSMSDispatcher对象,这个对象是干什么用的呢?
其实在对SMS的处理上,不同的制式也有不同的处理方法,与Phone对象类似,SMS同样抽象出来了一个SMSDispatcher类,他把各个制式对于SMS的处理中相同的部分抽象出来,而对于制式中不同的部分派生出了GsmSMSDispatcher子类和CdmaSMSDispatcher子类。
而我们主要关注GsmSMSDispatcher子类:
[java]viewplaincopy
∙@GsmSMSDispatcher.java
∙publicGsmSMSDispatcher(PhoneBasephone,SmsStorageMonitorstorageMonitor,SmsUsageMonitorusageMonitor){
∙super(phone,storageMonitor,usageMonitor);
∙mDataDownloadHandler=newUsimDataDownloadHandler(mCm);
∙//监测3个与SMS有关的状态
∙mCm.setOnNewGsmSms(this,EVENT_NEW_SMS,null);
∙mCm.setOnSmsStatus(this,EVENT_NEW_SMS_STATUS_REPORT,null);
∙mCm.setOnNewGsmBroadcastSms(this,EVENT_NEW_BROADCAST_SMS,null);
∙}
从上面可以看到,GsmSMSDispatcher的作用主要检测三种短消息事件。
而上面的mCm是在其父类SMSDispatcher中进行初始化的:
[html]viewplaincopy
∙@SMSDispatcher.java
∙protectedSMSDispatcher(PhoneBasephone,SmsStorageMonitorstorageMonitor,SmsUsageMonitorusageMonitor){
∙mPhone=phone;
∙//phone是GSMPhone,而phone的mCm就是RILJ
∙mCm=phone.mCM;
∙}
因此,在GsmSMSDispatcher构造函数中通过mCM.setOnNewGsmSms注册的监听器其实调用的是RILJ中的方法,而这个方法其实存在RILJ的父类BaseCommands中:
[java]viewplaincopy
∙@BaseCommands.java
∙publicvoidsetOnNewGsmSms(Handlerh,intwhat,Objectobj){
∙mGsmSmsRegistrant=newRegistrant(h,what,obj);
∙}
上面的过程,简单来说就是,在GSMPhone的构造函数中,创建了GsmSMSDispatcher的对象用于接收短消息,而GsmSMSDispatcher的初始化过程就是通过GSMPhone对象找到了RILJ(的父类),并把自己所关注的三种RIL层消息注册给RILJ,等待RILJ接收到短信时通知GsmSMSDispatcher。
二、RILJ通知GsmSMSDispatcher过程
下面我们来看,当有短消息上来时,RILJ如何把消息派发下去。
我们在《Framework层中的RIL》一文中分析过,在RILJ中有两个独立的线程,一个用于向RILC发送数据(RILSender),一个用于接收RILC层上报的数据(RILReceiver)。
当有新消息来时,一定会通过RILReceiver发送数据,而他又是通过processResponse处理数据的:
[java]viewplaincopy
∙@RIL.java
∙privatevoidprocessResponse(Parcelp){
∙inttype;
∙type=p.readInt();
∙//新消息是属于URC消息
∙if(type==RESPONSE_UNSOLICITED){
∙processUnsolicited(p);
∙}elseif(type==RESPONSE_SOLICITED){
∙}
∙}
[java]viewplaincopy
∙privatevoidprocessUnsolicited(Parcelp){
∙switch(response){
∙caseRIL_UNSOL_RESPONSE_NEW_SMS:
∙{
∙Stringa[]=newString[2];
∙a[1]=(String)ret;
∙SmsMessagesms;
∙sms=SmsMessage.newFromCMT(a);
∙if(mGsmSmsRegistrant!
=null){
∙//通过RILJ中的mGsmSmsRegistrant通知他的注册者,也就是GsmSMSDispatcher对象
∙mGsmSmsRegistrant.notifyRegistrant(newAsyncResult(null,sms,null));
∙}
∙break;
∙}
∙}
∙}
我们继续看notifyRegistrant的过程:
[java]viewplaincopy
∙@Registrant.java
∙publicvoidnotifyRegistrant(AsyncResultar)
∙{
∙internalNotifyRegistrant(ar.result,ar.exception);
∙}
∙voidinternalNotifyRegistrant(Objectresult,Throwableexception)
∙{
∙Handlerh=getHandler();
∙if(h==null){
∙clear();
∙}else{
∙Messagemsg=Message.obtain();
∙msg.what=what;
∙msg.obj=newAsyncResult(userObj,result,exception);
∙h.sendMessage(msg);
∙}
∙}
看来,RILJ对注册客户端的通知是通过sendMessage的方式实现的。
三、SMSDispatcher把短信通知发送到系统广播的过程
在这一步中,SMSDispatcher将把短信转换为Intent,并通过sendOrderedBroadcast发送到系统中。
上面分析到了sendMessage,还记得当初是GsmSMSDispatcher通过GSMPhone找到了RILJ,并为自己注册了三种关于SMS的监听。
[java]viewplaincopy
∙mCm.setOnNewGsmSms(this,EVENT_NEW_SMS,null);
∙mCm.setOnSmsStatus(this,EVENT_NEW_SMS_STATUS_REPORT,null);
∙mCm.setOnNewGsmBroadcastSms(this,EVENT_NEW_BROADCAST_SMS,null);
当前既然有了新的消息,RILJ通过sendMessage的方式发送的Message就会发送给GsmSMSDispatcher,而这个通知是在GsmSMSDispatcher的父类SMSDispatcher中被处理的:
[java]viewplaincopy
∙@SMSDispatcher.java
∙publicvoidhandleMessage(Messagemsg){
∙switch(msg.what){
∙caseEVENT_NEW_SMS:
∙//新消息的处理
∙SmsMessagesms;
∙ar=(AsyncResult)msg.obj;
∙sms=(SmsMessage)ar.result;
∙intresult=dispatchMessage(sms.mWrappedSmsMessage);
∙break;
∙
∙caseEVENT_SEND_SMS_COMPLETE:
//发送完成
∙caseEVENT_STOP_SENDING:
//停止发送
∙}
∙}
继续看dispatchMessage的过程,这个过程又进入到了子类GsmSMSDispatcher中处理:
[java]viewplaincopy
∙@GsmSMSDispatcher.java
∙publicintdispatchMessage(SmsMessageBasesmsb){
∙SmsMessagesms=(SmsMessage)smsb;
∙
∙if(mSmsReceiveDisabled){
∙//设备不支持短消息
∙returnIntents.RESULT_SMS_HANDLED;
∙}
∙
∙booleanhandled=false;
∙if(sms.isMWISetMessage()){
∙//新来语音信箱的短信通知
∙mPhone.setVoiceMessageWaiting(1,-1);//line1:
unknownnumberofmsgswaiting
∙handled=sms.isMwiDontStore();
∙}elseif(sms.isMWIClearMessage()){
∙//清除语音信箱的短信通知
∙mPhone.setVoiceMessageWaiting(1,0);//line1:
nomsgswaiting
∙handled=sms.isMwiDontStore();
∙}
∙
∙if(!
mStorageMonitor.isStorageAvailable()&&sms.getMessageClass()!
=SmsConstants.MessageClass.CLASS_0){
∙//存储不够,发送提示
∙returnIntents.RESULT_SMS_OUT_OF_MEMORY;
∙}
∙//普通短信处理
∙returndispatchNormalMessage(smsb);
∙}
上面对一些特殊条件进行处理,比如设备不支持短消息,或者接收到的消息是语音信箱提示、设备存储空间不足等,然后就进入普通消息的处理流程,而这个处理过程又进入了父类中:
[java]viewplaincopy
∙@SMSDispatcher.java
∙protectedintdispatchNormalMessage(SmsMessageBasesms){
∙SmsHeadersmsHeader=sms.getUserDataHeader();
∙
∙if((smsHeader==null)||(smsHeader.concatRef==null)){
∙byte[][]pdus=newbyte[1][];
∙pdus[0]=sms.getPdu();
∙
∙if(smsHeader!
=null&&smsHeader.portAddrs!
=null){
∙if(smsHeader.portAddrs.destPort==SmsHeader.PORT_WAP_PUSH){
∙//GSM-styleWAPindication
∙//Wappush信息的分发
∙returnmWapPush.dispatchWapPdu(sms.getUserData());
∙}else{
∙//Themessagewassenttoaport,soconcoctaURIforit.
∙dispatchPortAddressedPdus(pdus,smsHeader.portAddrs.destPort);
∙}
∙}else{
∙//普通短消息处理
∙dispatchPdus(pdus);
∙}
∙returnActivity.RESULT_OK;
∙}else{
∙SmsHeader.ConcatRefconcatRef=smsHeader.concatRef;
∙SmsHeader.PortAddrsportAddrs=smsHeader.portAddrs;
∙returnprocessMessagePart(sms.getPdu(),sms.getOriginatingAddress(),
∙concatRef.refNumber,concatRef.seqNumber,concatRef.msgCount,
∙sms.getTimestampMillis(),(portAddrs!
=null?
portAddrs.destPort:
-1),false);
∙}
∙}
这里看到,对于普通短消息,是通过dispatchPdus()接口分发出去的:
[java]viewplaincopy
∙protectedvoiddispatchPdus(byte[][]pdus){
∙//发送SMS_RECEIVED_ACTION的Intent
∙Intentintent=newIntent(Intents.SMS_RECEIVED_ACTION);
∙intent.putExtra("pdus",pdus);
∙intent.putExtra("format",getFormat());
∙//接收这个消息需要RECEIVE_SMS_PERMISSION的权限
∙dispatch(intent,RECEIVE_SMS_PERMISSION);
∙}
继续往下看:
[java]viewplaincopy
∙publicvoiddispatch(Intentintent,Stringpermission){
∙mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
∙//向系统中发送有序的广播,并且添加接收权限
∙mContext.sendOrderedBroadcast(intent,permission,mResultReceiver,this,Activity.RESULT_OK,null,null);
∙}
由此,Framework就通过SMSDispatcher将短消息用Broadcast的形式发送到了系统中。
四、总体流程图
现在贴出以上过程的流程图。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 短信 接收 过程 源码 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)