Android中SMS的接收处理

2024-04-01 04:08
文章标签 android 处理 接收 sms

本文主要是介绍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 = newRILReceiver();mReceiverThread =new Thread(mReceiver, "RILReceiver");mReceiverThread.start();

其中的类型

  • mReceiver: RILReceiver
  • mReceiverThread: Thread

 

RILReceiver实现了Runnable

RILReceiver

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

        public void run() {int retryCount= 0;try {for (;;) {LocalSockets = null;LocalSocketAddress l;try {s = newLocalSocket();l = newLocalSocketAddress(SOCKET_NAME_RIL,LocalSocketAddress.Namespace.RESERVED);s.connect(l);} catch (IOException ex){// 。。。}retryCount= 0;mSocket =s;int length= 0;try {InputStreamis = mSocket.getInputStream();for(;;) {Parcel p;length = readRilMessage(is, buffer);if(length < 0) {// End-of-stream reachedbreak;}p =Parcel.obtain();p.unmarshall(buffer, 0, length);p.setDataPosition(0);processResponse(p);p.recycle();}} catch(java.io.IOException ex) {// …} catch(Throwable tr) {// …}// …}} catch(Throwable tr) {Log.e(LOG_TAG,"Uncaught exception", tr);}}

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

   private void processResponse (Parcel p) {int type;type = p.readInt();if(type == RESPONSE_UNSOLICITED) {processUnsolicited (p);}else if (type == RESPONSE_SOLICITED) {processSolicited (p);}releaseWakeLockIfDone();}
 

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

 

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

              SmsMessage sms;sms = SmsMessage.newFromCMT(a);if (mSMSRegistrant != null) {mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));}

这里的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的处理:

           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 thatmessage was broadcast for app(s) to handle.// Any other result, weshould 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);}

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

 


这篇关于Android中SMS的接收处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866172

相关文章

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl