信息的接收工做是由底层来完成的,当有一个 新的信息时底层完成接收后会以Intent的方式来通知上层应用,信息的相关内容也包含在Intent当中,Android所支持的信息Intent都定义在android.provider.Telephony.Intents里面。 java
短信接收,对于上层应用程序来说就是要处理广播事件SMS_RECEIVED_ACTION,它是由Frameworks发出告诉上层有新的SMS已收到。在Mms中,是由PrivilegedSmsReceiver来处理,它收到SMS_RECEIVED_ACTION(android.provider.Telephony.Intents.SMS_RECEIVED_ACTION=”android.provider.Telephony.SMS_RECEIVED”)后会启动SmsReceiverService来作具体的处理。 android
SmsReceiverService会先检查短信的类型,若是是Class0短信,直接在GUI中显示,不作任何其余的处理,也即不会存储到数据库中,也不会在Notification Bar中作Notification。 数据库
对于其余短信,会进行替换现有的消息,或是看成新消息插入。原则就是若是在数据库中已有的短信中,与新来的短信的原始地址和协议标识都同样,那么就把其替换成新进的短信,不然就看成新短信插入。 数组
具体的替换流程:先用新进的短信生成一个ContentValues,再用短信的地址和协议标识看成条件到数据库中去查询,若是查到了,就替换,不然就存储。 ide
存储的流程,也是先生成一个CotentValues,而后取出短信的Thread Id和地址,地址要与联系人数据库同步一下,以保证是能识别的地址。若是Thread Id不是合法的,那么就用同步过的地址尝试从新生成Thread Id,尝试5次。而后把刷新过的Thread Id放到ContentValues中,把ContentValues插入到数据库中。若是设置为把信息存储到SIM卡,还要调用SmsManager把信息拷贝到SIM卡上。计算短信的大小,并更新至数据库。删除过时的短信,和超过数量限制的短信,而后返回插入后获得的短信Uri。 函数
最后,对于替换或插入的短信,用Uri去StatusBar作Notification。 工具
GUI在刷新列表时也能获得新短信,由于短信已经被存储到数据库中。 线程
彩信的接收过程与短信略有不一样,它主要是由应用程序负责从彩信服务中心(MMSC Multimedia Messaging Service Center)下载彩信信息。大体的流程是Frameworks会先发出一条短信,告知应用程序有一个彩信,短信中含有一些信息好比过时日期,发送者手机号码,彩信的URL等,而后应用程序自行经过HTTP取回URL所指的彩信内容。具体的流程为: 对象
Telephony Frameworks会先发出一个Intent:android.provider.Telephony.Intents.WAP_PUSH_RECEIVED_ACTION=”android.provider.Telephony.WAP_PUSH_RECEIVED”告知上层应用有一个彩信来了。这个Intent中会含有一个”data”byte数组(经过byte[] data = intent.getByteArrayExtra(“data”)来获取),这个Byte数组是关于这个彩信的一些信息的描述,它是一个NotificationInd,里面含有彩信的一些信息,好比发送者手机号码,彩信的ContentLocation(URL)。以后是由应用程序来决定如何作下一步的处理。 继承
在Mms中是由transaction.PushReceiver.java来接收WAP_PUSH_RECEIVED_ACTION,接收到彩信通知Intent后,它会作一些预处理,把data字段取出来,用Pdu的工具解析成为GenericPdu,而后转化为NotificationInd,并把它写入数据库,而后会启动TransactionService来作进一步的NOTIFICATION_TRANSACTION处理,同时把这个NotificationInd的Uri也传过去。
TransactionService被唤起,在其onStartCommand中会处理一下把PushReceiver所传来的Intent放入本身的MessageQueue中,而后在Handler.handleMessage()中处理TRANSACTION_REQUEST时处理NOTIFICATION_TRANSACTION。先是加载默认的一些彩信相关的配置信息,主要是MMSC,Proxy和Port,这些都是与运营商相关的信息,能够经过APN的设置来更改。TransactionService用PushReciver传来的NotificationInd的Uri和加载的配置信息TransactionSettings构建一个NotificationTransaction对象。以后,TransactionService检查其内的二个队列,或是加入Pending队列,或是直接处理(加入到正在处理队列),处理也是直接调用NotificationTransaction.process()。
NotificationTransaction的process()方法是继承自父类Transaction的方法,它只是简单的开启一个新的线程,而后返回,这样就可让Service去处理其余的Transaction Request了。
在线程中,首先从DownloadManager和TelephonyManager中加载一些配置信息,是否彩信设置为自动获取(auto retrieve),以及Telephony是否设置为数据延迟(DATA_SUSPEND),而后会采起不一样的措施,再从NotificationInd中取出彩信的过时日期。若是配置为不取数据(更确切的说,是不如今取数据),那么就先给DownloadManager的状态标记为STATE_UNSTARTED,再给MMSC发送一个Notify Response Indication,以后结束处理,函数返回,彩信的通知处理流程到此为止。用户能够经过操做UI,用其余方法手动下载彩信,这个会在后面详细讨论。
若是设置为自动获取或者数据传输是畅通的,那么就把DownloadManager状态标记为START_DOWNLOADING并开始下载彩信数据。彩信的获取是经过HTTP到彩信的ContentLocation(URL)取得数据。先是调用父类方法getPdu(),传入彩信的URL,最终调用HttpUtils的httpConnection方法发送HTTP GET请求,MMSC会把彩信数据返回,做为getPdu()的返回值返回。拿到的是一个byte数组,须要用Pdu的工具解析成为GenericPdu,而后用PduPersister把其写入数据库,再把彩信的大小更新到数据库,到这里一个彩信的接收就算完成了。剩下的就是,由于已经得到了彩信的数据,因此要把先前的通知信息(NotificationInd)删除掉,而后更新一下相关的状态,给MMSC返回Notify Response Indication,结束处理。由于数据库已经有所改变,因此UI会收到ContentChanged事件,刷新UI列表,新信息就会显示出来。
如前所述,若是彩信配置设置为不自动获取,那么UI刷新了后就会显示彩信通知:到期日期,彩信大小等,并提供一个”Download”按扭。用户能够点击按扭来下载彩信内容,点击按扭后,会启动TransactionService,把彩信通知的Uri,和RETRIEVE_TRANSACTION request打包进一个Intent传给TransactionService。TransactionService,像处理其余的Transaction同样,都是放进本身的MessageQueue,而后加载默认的TransactionSettings,构建RetrieveTransaction对象,而后处理调用RetrieveTransaction.process()。
RetrieveTransaction也是继承自Transaction,其process()也是建立一个线程,而后返回。在线程中,首先它用Pdu工具根据Uri从数据库中加载出彩信通知(NotificationInd),从NotificationInd中取得彩信的过时日期,检查过时日期,若是彩信已通过期,那么给MMSC发送Notify Response Indication。把DownloadManager状态标记为开始下载,而后若是彩信已过时,标记Transaction状态为Failed,而后返回,结束处理流程。若是一切正常,会用getPdu()从彩信的ContentLocation(URL)上面获取彩信内容,它会用HttpUtils.httpConnection()经过HTTP来获取,返回一个byte数组。用Pdu工具解析byte数组,获得GenericPdu,检查一下是不是新信息,是不是重复的信息,若是重复,标记状为失败,而后返回,结束处理。若是是新信息,先把GenericPdu用PduPersister写入数据库中,更新信息大小和ContentLocation(URL)到数据库中,到这里一个彩信其实已经所有获取完了。接下来就是发送收到确认信息给MMSC,标记处理状态为成功,结束处理。这时UI应该监听到数据库变化,并刷新,新信息应该会显示给用户。
总结,与信息发送相似,数据库在接收信息过程当中也扮演了重要角色,信息接收到后进行解析,而后就写入数据库,与发送不一样,接收的信息没有那么多状态,一旦写入了数据库就意味着信息接收已经成功,UI也是只监听数据库的变化,一旦有变化马上刷新显示信息。