`
mmdev
  • 浏览: 12934704 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Android中SMS的接收处理

 
阅读更多

田海立

2012-02-22

在解析WAP PUSH over SMS时,看了一下Android里SMS接收的流程,并按照自己需要的流程记录,其他分支的详细处理并未讲述。PDU数据的encode/decode也并未在本文中进行解析,有兴趣的读者可以到相应的代码处自己解读一下。

Android中,RIL用RILReciever接收SMS pdu,并根据不同的信息类型用相应函数来处理。因手机制式的差异,用GsmSmsDispatcher或CdmaSmsDispatcher来做各自的消息处理并分发。最后的分发是通过发送相应的Broadcast,所以,对感兴趣的消息处理,可以注册Receiver来监听相应的Broadcast,实现自己的SMS/MMS/Wap push,以及其他类型消息的接收处理。

RIL构造函数中,Receiver的初始化[在文件RIL.java中]


其中的类型

  • mReceiver: RILReceiver
  • mReceiverThread: Thread

RILReceiver实现了Runnable

RILReceiver

关注RILReceiver线程的实现[在RILReceiver::run()中]


RILReceiver线程不停的监听本地Socket,读到数据之后在processResponse()[Line#37]中处理。

如果类型属于Unsolicited消息,则在processUnsolicited()中处理。收到的短信是属于Unsolicited信息,看它的实现。

processUnsolicited()中很长的switch… case语句中对收到短信的处理在case RIL_UNSOL_RESPONSE_NEW_SMS:


这里的SmsMessage是android.telephony.SmsMessage。newFromCMT()中会根据电话类型(GSM/CDMA)选择具体的SmsMessage进行封装(因为Rational Rose中,同一工程中,不同包内的类也不允许同名,com.android.internal.telephony.gsm.SmsMessage用gsm.SmsMessage代替;com.android.internal.telephony.cdma.SmsMessage用cdma.SmsMessage代替。实际类型都是SmsMessage)。

SmsMessage

mSMSRegistrant是RIL父类的成员。通过setOnNewSMS()/unSetOnNewSMS()设置和取消设置。SMSDispatcher的构造函数中注册了SMS的Registrant

mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);

Regstrant

所以,调用mSMSRegistrant.notifyRegistrant(newAsyncResult(null, sms, null))之后,执行的是SMSDispatcher中Handler在handleMessage()中对EVENT_NEW_SMS的处理:


SMSDispatcher是一个abstract的类,dispatchMessage()的具体实现在GsmSMSDispatcherCdmaSMSDispatcher中。

GsmSMSDispatcher::dispatchMessage()中,会对Class 0类型的短信,有目标端口的短信,和长短信做处理。

目标端口为WAPPUSH的信息,则调用mWapPush.dispatchWapPdu(sms.getUserData(),pdus)让WAPPUSH来处理;其它未知的端口,则用“sms://localhost:<port>”指定端口。

对长短信,调用processMessagePart()进行组合处理。

1)有目标端口且目标端口是WAP PUSH(SmsHeader.PORT_WAP_PUSH)的信息,用WapPushOverSms::dispatchWapPdu()来处理:

根据不同的contentType:

-> dispatchWapPdu_PushCO();

-> dispatchWapPdu_MMS();

-> dispatchWapPdu_default()

2)有目标地址且目标端口不是WAP PUSH的信息,在SMSDispatcher::dispatchPortAddressedPdus()中处理:

Uri uri =Uri.parse("sms://localhost:" + port);

Intent intent= new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);

intent.putExtra("pdus", pdus);

dispatch(intent, "android.permission.RECEIVE_SMS");

3)通常的无目标地址的信息(普通短信),在SMSDispatcher::dispatchPdus()中处理:

Intent intent= new Intent(Intents.SMS_RECEIVED_ACTION);

intent.putExtra("pdus", pdus);

dispatch(intent, "android.permission.RECEIVE_SMS");


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics