第7章 短信发送过程部分内容

本文深入剖析了Android系统中短信发送的过程,从用户界面的短信编辑到后台的短信发送请求,详细介绍了短信发送的各个阶段,包括短信编辑、发送请求的处理、短信的拆分、数据库操作、短信发送状态报告等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第7章 短信发送过程部分内容

1、短信应用包路径为packages/apps/Mms,查看配置文件AndroidManifest.xml文件,可以找到MMs应用的入口,就是ConversationList.java。

图7.1查看短信的入口

2、在默认的Android虚拟设备启动时,进入ConversationList.java显示短信的会话列表界面,不会有任何短信会话。

在ConversationList.java显示的短信会话列表界面,点击屏幕左下角的“新建短信”,进入短信编辑界面。此按钮的响应事件是ConversationList类中的createNewMessage(),他最主要的作用就是启动ComposeMessageActivity类的Activity。

 

图7.2启动ComposeMessageActivity类

  1. 在ComposeMessageActivity类里面,可以编辑短信的标题、内容等。当我们编辑好了,点击发送,会响应当前类里面的onClick方法,在onclick方法里面会调用confirmSendMessageIfNeeded()方法。(在10390行处)

 

图7.31发送短信调用confirmSendMessageIfNeeded()

confirmSendMessageIfNeeded()方法:

 

图7.32获取isMms,调用sendMsimMessage()、sendMessage()

sendMsimmessage()方法:

图7.33 sendMsimmessage()调用sendMessage()方法

 

confirmSendMessageIfNeeded()有两大作用:

  1. 获取编辑内容是短信还是彩信的标志isMms,并根据此标志判断输入的是短信接收方的地址是否正确,如果不正确弹出相应的信息提示。
  2. 调用当前类中的sendMessage方法中的处理逻辑,sendMessage方法最关键的是调用mWorkingMessage.send()继续发起发送短信的请求调用。

mWorkingMessage是WorkingMessage类型,当前编辑的短信内容被抽象成了WorkingMessage类,他实现了当前编辑的短信信息涉及的所有行为和操作,其中包含:发送当前信息、为当前信息增加主题或者附件、设置当前信息的类型(短信或者彩信)、保存草稿、丢弃当前信息、设置当前信息所属的会话等。

 

图7.4 sendMessage方法调用mWorkingMessage.send()

接着看一下WorkingMessage的send()

        ……

// 准备往磁盘中写

//短信和彩信分开处理,if中处理发送彩信,else中处理发送短信

//准备发送彩信所需要的参数如:mmsUri、persister、slideshow等

//启动线程完成发送短信的操作,目的是不影响界面的返回。

sendMmsWorker(…)//调用sendMmsWorker返回继续发送短信的请求;

updateSendStates()//更新Conversation列表的界面显示。

 

 

 

 

//启动线程发送短信的操作,目的是不影响界面的返回;

sendMmsWorker(…)//调用sendMmsWorker返回继续发送短信的请求;

 

图7.5 WorkingMessage处理短信发送

总结:WorkingMessage类应该看作发送短信的起点,在发送短信的时候首先调用其send方法。他的if…else分别处理发送彩信、短信,如果发送短信,将当前类中的preSendSmsWorker方法继续调用sendSmsWork方法,而sendSmsWork方法中的处理逻辑主要分为两步:

  1. 创建SmsMessageSender对象sender
  2. 调用sender.sendMessage继续发起发短信的请求。

图7.6 preSendSmsWorker方法调用sendSmsWork()

 

图7.7 sendSmsWork()创建SmsMessageSender对象sender,调用sender.sendMessage

  1. SmsMessageSender类,短信发送处理。

图7.8 sender.sendMessage()调用queueMessage()

……

//循环处理多个短信接收方

……

 

 

//调用Telephony Framework层中的addMessageToUri静态方法,记录待发送的短信的内容(将需要发送的短信内容保存到数据库)

//数据库操作异常

 

//发送ACTION_SEND_MESSAGE广播,SmsReceiver类中的onReceiver方法会接收。

 

图7.9发送ACTION_SEND_MESSAGE广播

6、SmsReceiver类中的onReceiver方法接受广播。

 

图7.10调用onReceiveWithPrivilege()

onReceiveWithPrivilege()方法详细作用:

 

图7.11启动SmsReceiverService

通过AIDL启动SmsReceiverService,进入SmsReceiverService类的onStartCommand方法。

7、SmsReceiverService

进入SmsReceiverService类的onStartCommand方法。此方法通过mServiceHandler对象,在当前类中进行Handler消息的发送和接收处理。在handleMessage方法中,根据Action请求的不同类型,分为4个分支,在短信发送请求的过程中,进入ACTION_SEND_MESSAGE分支调用handleSendMessage方法,而handleSendMessage方法会继续调用sendFirstQueuedMessage方法继续传递发送短信的请求。

 

图12 SmsReceiverService类的onStartCommand(),执行mServiceHandler.sendMessage(msg)将消息发给自己,然后去自己的handleMessage()处理

接着会进入自己的handleMessage处理,接收到的消息是第5步发送ACTION_SEND_MESSAGE广播,然后会调用handleSendMessage()方法。

 

图13 handleMessage处理调用handleSendMessage()

看一下handleSendMessage(),handleSendMessage()继续调用sendFirstQueuedMessage()继续传递发送短信的请求。

 

图14 handleSendMessage()调用sendFirstQueuedMessage()

sendFirstQueuedMessage()方法的处理逻辑是从数据库中读取等待发送的短信的内容,根据短信内容创建SmsSingleRecipientSender对象,并调用其sendMessage方法,继续发出发送短信的请求。

//从数据库中获取要发送的短信的内容

 

……

//根据短信的内容创建SmsSingleRecipientSender对象

//调用他的sendMessage方法

图15数据库中获取短信内容,调用SmsSingleRecipientSender对象的sendMessage

 

 

8、SmsSingleRecipientSender类:

查看SmsSingleRecipientSender对象的sendMessage()方法:

……

//获取SmsManager对象,SmsManager位于Telephony framework层

 

//根据彩信内容拆分出单个或者多个彩信

//根据短信内容长短拆分出单个或者多个短信

 

//验证拆分出来的短信个数是否正常,以及异常处理

 

//通过sms类的静态方法调用,将即将发送的短信保存到发件箱中

//deliveryIntents和sentIntents两个list增加对应的Intent对象

 

//调用Telephony Frameworks层中的方法,继续发起短信发送请求

图16 SmsSingleRecipientSender对象的sendMessage()方法

总结:SmsSingleRecipientSender对象的sendMessage()方法

  1. 调用SmsManager对象的divideMessage方法,完成短信的拆分;国内短信中的内容超过160byte,将会进行拆分;
  2. 调用Sms类中的静态方法moveMessageToFolder,将即将发送的短信移动到发件箱;
  3. deliveryIntents用于短信发送状态报告的回调Intent,sentIntent作为短信发送结果的回调intent;
  4. 调用SmsManager对象的sendMultipartTextMessage方法,完成单挑或者多条短信的发送。
    1. SmsManager类

SmsManager类在TelePhony Framework层提供短信操作的相关接口供应用层调用。该类提供了短信的拆分、发送、将短信复制到SIM卡上、从SIM卡上删除短信、小区广播等操作接口。

1) 首先获取SmsManager对象并调用它的getDefault方法;其次,调用SmsManager对象的divideMessage方法完成短信的拆分、调用SmsManager对象的sendMultipartTextMessage方法完成短信的发送。

注意:是Telephony目录下的,不是Telephony gsm目录下的SmsManager。

 

图17  调用sendMultipartTextMessageInternal()

2) sendMultipartTextMessageInternal()方法介绍:

 

//判断短信的长度

//获取IccSmsInterfaceManager服务,调IccSmsInterfaceManager服务发送短信接口

//获取单个的deliveryIntent和sentIntent

 

图18 sendMultipartTextMessage间接调IccSmsInterfaceManager服务发送短信接口

3)IccSmsInterfaceManager服务发送短信接口:这里拿发送多条短息举例,单条短信发送与其相似。

UiccSmsController.javasendMultipartTextForSubscriber方法,该方法会调用IccSmsInterfaceManager服务发送短信接口。

图18该方法会调用IccSmsInterfaceManager服务发送短信接口,并调用他发送短信的方法

IccSmsInterfaceManager服务发送短信接口:

 

图19获取短信发送接口

 

图20调mDispatcher的方法发送短信

mDispatcher对象是SMSDispatcher类型的,字面理解“短信分发器”,他的创建与Tracker对象的创建时机一样,均是在Phone对象创建时同时构造。

总结:

SmsManager对象接收到sendMultipartTextMessage方法调用,分别处理长短信发送和普通短信发送;最后是调用RIL对象提供的sendSMS方法,完成短信发送的RIL请求调用。

短信发送到短信中心之后,RIL会向SMSDispatcher发起EVENT_SEND_SMS_COMPLETE类型的消息通知,SMSDispatcher对象最终调用handleSendComplete方法响应短信发送的返回结果。

    1. SMSDispatcher类

SMSDispatcher的sendText与sendMultipartText处理逻辑一样,可以分为两步:

1)将短信内容构造为SubmitPdu;

2)调用mCm.sendSMS方法向RIL发起短信发送请求。

SMSDispatcher短信分发器从调用sendText与sendMultipartText,到最后与RIL的交互,在这期间还会调用sendRawPdu、sendSms方法。

 

图21 mCi是RIL对象

mCi是RIL对象。至此短信传到了RIL层,短信请求从应用层分多个步骤传到Java Frameworks层,最后是Java Frameworks框架层拆分短信、创建PDU对象等操作,最终会调用RIL对象中发送短信的方法,将短信发送的请求转换为对应的RIL请求调用。

短信发送成功会保存对应的tracker对象到deliveryPendingList,在处理短信状态报告的同时会发出sentIntent的广播通知。短信发送失败有3次短信重发的处理机制。

 

图22保存对应的tracker对象到deliveryPendingList

图23调用onSent()发出sentIntent的广播通知

总结:短信发送成功决定性因素:

手机Modem将短信成功发送到短信中心;

短信中心成功发送短信到短信接收方。

    1. 短信发送状态处理机制

在与RIL交互的时候,将RIL请求处理的结果CallBack回调handler消息对象作为参数传递给RIL对象,RIL发起短信发送的AT命令,Modem将短信发送出去并将结果告诉RIL,RIL接收到response后将使用对应的handler对象发送消息通知进行回调;

1)接着查看GsmSMSDispatcher对象中的sendSms方法,向RIL发出短信发送请求。

 

图24sendSms方法调用sendSmsByPstn()

sendSmsByPstn()方法中

//创建回调的handler消息对象,消息类型为EVENT_SEND_SMS_COMPLETE

Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);

//调用RI了对象的发送短信请求方法

mCi.sendSMS(……);

 

图25 tracker会保存在replay里面,传给RIL

看一下tracker

 

图26

2)SMSDispatcher会接收RIL对象发起的CallBack通知,在handleMessage中处理消息类型为EVEVT_SEND_SMS_COMPLETE消息。然后handleMessage会调用handlesendComplete方法处理。

 

总结:

1)SmsTracker对象在SMSDispatcher中创建,并传递给RIL,最后RIL对象会发出EVEVT_SEND_SMS_COMPLETE消息,该消息中仍然保存了SMSTracker对象,可见他是一直存在在SMSDispatcher与RIL对象的短信发送的请求的返回过程中。

2)通过SMSTracker对象获取sentIntent,并发出广播通知,根据sentIntent的创建过程,找到在SmsReceiver类中的onReceive方法接收此广播,然后启动SmsReceiverService服务,并在handleSmsSent方法中最终处理发送短信的返回结果。

3)短信如果发送失败,会有三次重发的机制,在SMSDispatcher类中的handleSendComplete方法中处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值