信息的接收工作是由底层来完成的,当有一个 新的信息时底层完成接收后会以Intent的方式来通知上层应用,信息的相关内容也包含在Intent当中,Android所支持的信息Intent都定 义在android.provider.Telephony.Intents里面。

短信的接收

短信接收,对于上层应用程序来讲就是要处理广播事件SMS_RECEIVED_ACTION,它是由Frameworks发出告诉上层有新的SMS已收 到。在Mms中,是由PrivilegedSmsReceiver来处理,它收到 SMS_RECEIVED_ACTION(android.provider.Telephony.Intents.SMS_RECEIVED_ACTION=”android.provider.Telephony.SMS_RECEIVED”) 后会启动SmsReceiverService来做具体的处理。

SmsReceiverService会先检查短信的类型,如果是Class0短信,直接在GUI中显示,不做任何其他的处理,也即不会存储到数据库中,也不会在Notification Bar中做Notification。

对于其他短信,会进行替换现有的消息,或是当作新消息插入。原则就是如果在数据库中已有的短信中,与新来的短信的原始地址和协议标识都一样,那么就把其替换成新进的短信,否则就当作新短信插入。

具体的替换流程:先用新进的短信生成一个ContentValues,再用短信的地址和协议标识当作条件到数据库中去查询,如果查到了,就替换,否则就存储。

存储的流程,也是先生成一个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也是只监听数据库的变化,一旦有变化立刻刷新显示信息。

Android Mms 接收信息流程的更多相关文章

  1. [Android] hid设备按键流程简述

    hexdump /dev/hidraw0就能看到usbhid设备传输过来的裸流 如:按下Input键 003ae60 0000 0096 8000 006b 0000 0000 0000 0000 * ...

  2. Android Mms专题之:Mms源码结构

    从软件的功能角度来讲,Mms分为对话列表,消息列表,短信编辑,彩信编辑,短信显示,彩信显示和配置. 从实现的角度来看,它分为GUI展示层,发送/接收,彩信解析,彩信附件,信息数据等,这些分类对应着源码 ...

  3. Android Mms之:深入MMS支持

    Composing and editing MMS在Android Mms应用里面的具体实现形式,或数据结构是SlideshowModel,它是一个每个节点为SlideModel的ArrayList, ...

  4. Android process 的启动流程

    Android process 的启动流程 1.android启动时所运行的进程: USER    PID     PPID    VSIZE    RSS    WCHAN         PC   ...

  5. Android窃取用户信息新思路

    0×01 我们能得到哪些android手机上的app敏感信息手机上的app敏感信息◦通讯录,通讯记录,短信◦各种app的帐号密码,输入信息资料等◦各种影音资料,照片资料◦等等0×02  我们有哪些方法 ...

  6. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2 ...

  7. Android开机动画启动流程

    android开机动画启动流程   从android的Surface Flinger服务启动分析知道,开机动画是在SurfaceFlinger实例通过调用startBootAnim()启动的. 下面我 ...

  8. Android系统开机启动流程及init进程浅析

    Android系统启动概述 Android系统开机流程基于Linux系统,总体可分为三个阶段: Boot Loader引导程序启动Linux内核启动Android系统启动,Launcher/app启动 ...

  9. Android之SystemUI载入流程和NavigationBar的分析

    Android之SystemUI载入流程和NavigationBar的分析 本篇仅仅分析SystemUI的载入过程和SystemUI的当中的一个模块StatusBar的小模块NavigationBar ...

随机推荐

  1. [转] C#操作EXCEL,生成图表的全面应用

    gailzhao 原文 关于C#操作EXCEL,生成图表的全面应用 近来我在开发一个运用C#生成EXCEL文档的程序,其中要根据数据生成相应的图表,该图表对颜色和格式都有严格的要求,在百度和谷歌中搜索 ...

  2. 3. 使用绘图API自定义视图 --- 旋转的方块

    import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; impor ...

  3. firebug console使用

    Firebug内置一个console对象,提供5种方法,用来显示信息. console.log("Hello World") console.info("这是info&q ...

  4. web自动化框架之一介绍与环境搭建(Selenium+Eclipse+Python)

    看到一篇环境搭建文章,详细又全面,这里就不一一重复了 http://blog.csdn.net/dyllove98/article/details/9390649 其它: 1.框架介绍      整个 ...

  5. redo文件三

    switch logfile是一种昂贵的操作,在进行日志切换的时候,是不允许生成新的redo信息 在前台进程生成redo日志信息的时候,此时redo buffer已经分配了空间,并且在当前的redo日 ...

  6. 【SummaryPlan】Summary of Feb & Plan of March——How to 'just do it'?

    Why I choose to be a graduate student from an undergraduate student? It’s time to applying for inter ...

  7. picture to string

    图片转化为字符原理: 一张m*n大小的图片,实际上可以看成是一个m*n的矩阵.矩阵的每一个元素就是一个Color值,不同的Color值,用不同的Ascii可以在屏幕上打印显示的字符来代替,于是可以得到 ...

  8. codeforces 630R Game

    R. Game time limit per test 0.5 seconds memory limit per test 64 megabytes input standard input outp ...

  9. 新手指南:详解Linux Top 命令

    Linux top命令简介 top 命令是最流行的性能监视工具之一,我们必需了解.它是一个优秀的交互式工具,用于监视性能.它提供系统整体性能,但报告进程信息才是 top 命令的长处.top 命令交互界 ...

  10. 网络复习之TCP

    可靠传输的工作原理 1 停止等待协议 每发送完一个分组,就停止发送,等待对方确认.出现差错,超时重传.     1.1 暂时保留已发送的分组的副本     1.2 分组和确认分组必须进行编号     ...