短信是手机通信模块的重要组成部分,本次主要简单谈谈短信的发送流程,让大家对短信模块有个简单的了解。
信息的发送,对于Mms应用程序来讲主要就是在信息数据库中创建并维护一条信息记录,真正的发送过程交由底层(Frameworks层)函数来处理。
当信息创建完成后,对于信息通常有三个选择,一个是放弃这个信息;第二个就是保存为草稿;最后一个就是发送此信息
1、短信在应用层的发送
ComposeMessageActivity.java是会话界面,当点击发送按钮之后,短信的发送就开始了。在会话界面,短信主要是通过调用sendMessage()方法来进行发送出去的,在调用这一方法之前,短信还会调用confirmSendMessageIfNeeded()方法来判断短信收件人中是否含有非法的收件人。
ComposeMessageActivity.confirmSendMessageIfNeeded()
ComposeMessageActivity
短信在调用confirmSendMessageIfNeeded()方法来判断短信收件人中是否含有非法的收件人之后,就直接进入sendMessage()方法来进行发送短信。 在sendMessage()方法中,还要判断短信内容是否需为彩信以及手机是否处于紧急拨号的模式。若是短信内容为彩信,则需要进行彩信的发送。若是处于紧急拨号模式,就会回调接口弹出提示信息(目前很多项目在紧急模式的情况下会对发送键置灰,使短信无法发送)。
WorkingMessage.java
在WorkingMessage.java中,拿到一个要发送的消息后,刷新收信人,判断信息类型,然后就会对短信和彩信彩取不同的处理流程。对于短信,WorkingMessage除了刷新联系人外,不会再做其他的事情,它会创建SmsMessageSender并调用其sendMessage()方法来发送信息。在构造SmsMessageSender对象是传入相关的参数收信人地址(是以分号分隔的一串字符),信息内容和所在对话的ID(threadId) 。构造完成后,直接调用其sendMessage()方法即可,接下来SmsMessageSender会处理所有的事情。在交由SmsMessageSender处理之前,WorkingMessage会回调UI一次,以让UI刷新收信人编辑框和信息文本输入框。
在WorkingNessage.send方法主要为区分短信彩信的发送,短信发送时就调用preSendSmsWorker()方法进行。
SmsMessageSender.java
SmsMessageSender.java主要工作为:
1、获取发送报告设置的状态;
2、将消息按照收件人拆开成多条消息,并加入消息队列;
3、发送广播通知SmsReceiverService来发送短信。
SmsReceiverService.java
SmsMessageSender发出的广播是由SmsReceiver来接收,当SmsReceiver接收到广播之后,就会启动服务SmsReceiverService。 SmsReceiverService是短信(SMS)处理的Service,负责短信的发送和接收,在得到发送短信息指令(ACTION_SEND_MESSAGE)后会从消息队列中读出第一个短信,然后创建SmsSingleRecipientSender对象,传入收信人地址,消息内容,所属的threadid和短信的Uri,并调用其sendMessage()发送这个短信。
SmsReceiverService.java
在以上代码中,当得到发送短信的指令后,handleSendMessage ()会对短信的发送情况进行判断,如果没有短信正在发送,就会调用sendFirstQueuedMessage()方法,查询队列中的信息,并取出队列中的第一条消息后进行发送。它发送的只是单个联系人的信息,具体的实现为调用SmsSingleRecipientSender.sendMessage()的方法。
SmsReceiverService.java
SmsSingleRecipientSender.java
SmsSingleRecipientSender会调用SmsManager的方法divideMessage()来把短信分成适合发送的几个部分,因为可能信息过长,不能一次发送完成,所以就需要分成几部分来分次发送。同时会把消息移动到发件箱。然后会针对分割的每一部分都会创建两个PendingIntent,这两个PendingIntent都是给底层用的,一个用于当短信被发送出去时广播出来,另一个是在短信已被收信人接收到时广播出来。所以两个广播的作用是,一个可用于标识短信已发送,另一个则可以作为送达的通知。最后调用SmsManager.sendMultipartTextMessage交由底层来发送短信。
应用层
信息已发送广播由SmsReceiverService监听,但是信息已送到收件人手上的广播则是由MessageStatusReceiver监听的。他们收到广播之后,会从Intent中取得详细的发送和送达状态,然后更新数据库中信息的状态(status),UI当发现数据库变化后,就会更新UI。
短信在底层(frameworks)的发送
2、短信在底层(frameworks)的发送
Frameworks层
在frameworks层,SmsManager会根据发送的短信的情况分为长短信和非长短信两种情况进行处理。
在android系统中,内置了CDMA和GSM两种模式来进行短信的发送处理
对于GSM,直接调用handleStatusReport方法处理,从传入的AsyncResult对象中获取SmsMessage进而获取SmsTracker的索引,从deliveryPendingList中取出SmsTracker,发送deliveryIntent并发送消息确认。
对于CDMA,在handleMessage中转到EVENT_NEW_SMS,调用dispatchMessage进行消息的分发。
由于RIL.java是中间层和rild守护进程通信的一个入口,从这可以将对应的操作在rild中去完成
到此为止RIL.java已经将发送操作传递给守护进程rild,那剩下的操作就由守护进程和猫这端来完成了。
经过这些步骤已经能够将短信发送出去了。