Android短信接收过程源码分析
一、GsmSMSDispatcher注册监听过程
在《Framework层中的RIL》一文中我们介绍过,Framework与应用层中的Phone对象其实就是用GSMPhone对象生成的PhoneProxy对象(CDMA制式不谈)。可以简单的理解为Phone就是GSMPhone对象。而GSMPhone又是Framework中与RIL层沟通的对象,因此我们从GSMPhone开始入手分析。
- @GSMPhone.java
- public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
- //调用父类PhoneBase的构造函数,在内部实现一下赋值:phone.mCM=ci=RILJ
- super(notifier, context, ci, unitTestMode);
- //初始化GsmSMSDispatcher,用于派发短消息
- mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
- }
其实在对SMS的处理上,不同的制式也有不同的处理方法,与Phone对象类似,SMS同样抽象出来了一个SMSDispatcher类,他把各个制式对于SMS的处理中相同的部分抽象出来,而对于制式中不同的部分派生出了GsmSMSDispatcher子类和CdmaSMSDispatcher子类。
而我们主要关注GsmSMSDispatcher子类:
- @GsmSMSDispatcher.java
- public GsmSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor, SmsUsageMonitor usageMonitor) {
- super(phone, storageMonitor, usageMonitor);
- mDataDownloadHandler = new UsimDataDownloadHandler(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);
- }
- @SMSDispatcher.java
- protected SMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor, SmsUsageMonitor usageMonitor) {
- mPhone = phone;
- //phone是GSMPhone,而phone的mCm就是RILJ
- mCm = phone.mCM;
- }
- @BaseCommands.java
- public void setOnNewGsmSms(Handler h, int what, Object obj) {
- mGsmSmsRegistrant = new Registrant (h, what, obj);
- }
上面的过程,简单来说就是,在GSMPhone的构造函数中,创建了GsmSMSDispatcher的对象用于接收短消息,而GsmSMSDispatcher的初始化过程就是通过GSMPhone对象找到了RILJ(的父类),并把自己所关注的三种RIL层消息注册给RILJ,等待RILJ接收到短信时通知GsmSMSDispatcher。
二、RILJ通知GsmSMSDispatcher过程
下面我们来看,当有短消息上来时,RILJ如何把消息派发下去。我们在《Framework层中的RIL》一文中分析过,在RILJ中有两个独立的线程,一个用于向RILC发送数据(RILSender),一个用于接收RILC层上报的数据(RILReceiver)。当有新消息来时,一定会通过RILReceiver发送数据,而他又是通过processResponse处理数据的:
- @RIL.java
- private void processResponse (Parcel p) {
- int type;
- type = p.readInt();
- //新消息是属于URC消息
- if (type == RESPONSE_UNSOLICITED) {
- processUnsolicited (p);
- } else if (type == RESPONSE_SOLICITED) {
- }
- }
- private void processUnsolicited (Parcel p) {
- switch(response) {
- case RIL_UNSOL_RESPONSE_NEW_SMS:
- {
- String a[] = new String[2];
- a[1] = (String)ret;
- SmsMessage sms;
- sms = SmsMessage.newFromCMT(a);
- if (mGsmSmsRegistrant != null) {
- //通过RILJ中的mGsmSmsRegistrant通知他的注册者,也就是GsmSMSDispatcher对象
- mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
- }
- break;
- }
- }
- }
- @Registrant.java
- public void notifyRegistrant(AsyncResult ar)
- {
- internalNotifyRegistrant (ar.result, ar.exception);
- }
- 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);
- }
- }
看来,RILJ对注册客户端的通知是通过sendMessage的方式实现的。
三、SMSDispatcher把短信通知发送到系统广播的过程
在这一步中,SMSDispatcher将把短信转换为Intent,并通过sendOrderedBroadcast发送到系统中。上面分析到了sendMessage,还记得当初是GsmSMSDispatcher通过GSMPhone找到了RILJ,并为自己注册了三种关于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);
- @SMSDispatcher.java
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_NEW_SMS:
- //新消息的处理
- SmsMessage sms;
- ar = (AsyncResult) msg.obj;
- sms = (SmsMessage) ar.result;
- int result = dispatchMessage(sms.mWrappedSmsMessage);
- break;
- case EVENT_SEND_SMS_COMPLETE: //发送完成
- case EVENT_STOP_SENDING://停止发送
- }
- }
- @GsmSMSDispatcher.java
- public int dispatchMessage(SmsMessageBase smsb) {
- SmsMessage sms = (SmsMessage) smsb;
- if (mSmsReceiveDisabled) {
- //设备不支持短消息
- return Intents.RESULT_SMS_HANDLED;
- }
- boolean handled = false;
- if (sms.isMWISetMessage()) {
- //新来语音信箱的短信通知
- mPhone.setVoiceMessageWaiting(1, -1); // line 1: unknown number of msgs waiting
- handled = sms.isMwiDontStore();
- } else if (sms.isMWIClearMessage()) {
- //清除语音信箱的短信通知
- mPhone.setVoiceMessageWaiting(1, 0); // line 1: no msgs waiting
- handled = sms.isMwiDontStore();
- }
- if (!mStorageMonitor.isStorageAvailable() && sms.getMessageClass() != SmsConstants.MessageClass.CLASS_0) {
- //存储不够,发送提示
- return Intents.RESULT_SMS_OUT_OF_MEMORY;
- }
- //普通短信处理
- return dispatchNormalMessage(smsb);
- }
- @SMSDispatcher.java
- protected int dispatchNormalMessage(SmsMessageBase sms) {
- SmsHeader smsHeader = sms.getUserDataHeader();
- if ((smsHeader == null) || (smsHeader.concatRef == null)) {
- byte[][] pdus = new byte[1][];
- pdus[0] = sms.getPdu();
- if (smsHeader != null && smsHeader.portAddrs != null) {
- if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
- // GSM-style WAP indication
- //Wap push 信息的分发
- return mWapPush.dispatchWapPdu(sms.getUserData());
- } else {
- // The message was sent to a port, so concoct a URI for it.
- dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
- }
- } else {
- //普通短消息处理
- dispatchPdus(pdus);
- }
- return Activity.RESULT_OK;
- } else {
- SmsHeader.ConcatRef concatRef = smsHeader.concatRef;
- SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs;
- return processMessagePart(sms.getPdu(), sms.getOriginatingAddress(),
- concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount,
- sms.getTimestampMillis(), (portAddrs != null ? portAddrs.destPort : -1), false);
- }
- }
- protected void dispatchPdus(byte[][] pdus) {
- //发送SMS_RECEIVED_ACTION的Intent
- Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
- intent.putExtra("pdus", pdus);
- intent.putExtra("format", getFormat());
- //接收这个消息需要RECEIVE_SMS_PERMISSION的权限
- dispatch(intent, RECEIVE_SMS_PERMISSION);
- }
- public void dispatch(Intent intent, String permission) {
- mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
- //向系统中发送有序的广播,并且添加接收权限
- mContext.sendOrderedBroadcast(intent, permission, mResultReceiver, this, Activity.RESULT_OK, null, null);
- }
由此,Framework就通过SMSDispatcher将短消息用Broadcast的形式发送到了系统中。
四、总体流程图
现在贴出以上过程的流程图。