您的位置:首页 > 移动开发 > Android开发

Android7.0 Messaging源码分析(5) - MMS类库篇

2016-11-18 14:05 288 查看
《Android7.0 Messaging源码分析(2) - Application 创建篇》中介绍了在 application 创建过程中会初始化MMS类库,这篇文章对 MMS 类库做简要分析。

初始化代码如下:

138    private static void initMmsLib(final Context context, final BugleGservices bugleGservices,
139            final CarrierConfigValuesLoader carrierConfigValuesLoader) {
140        MmsManager.setApnSettingsLoader(new BugleApnSettingsLoader(context));
141        MmsManager.setCarrierConfigValuesLoader(carrierConfigValuesLoader);
142        MmsManager.setUserAgentInfoLoader(new BugleUserAgentInfoLoader(context));
143        MmsManager.setUseWakeLock(true);
144        // If Gservices is configured not to use mms api, force MmsManager to always use
145        // legacy mms sending logic
146        MmsManager.setForceLegacyMms(!bugleGservices.getBoolean(
147                BugleGservicesKeys.USE_MMS_API_IF_PRESENT,
148                BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT));
149        bugleGservices.registerForChanges(new Runnable() {
150            @Override
151            public void run() {
152                MmsManager.setForceLegacyMms(!bugleGservices.getBoolean(
153                        BugleGservicesKeys.USE_MMS_API_IF_PRESENT,
154                        BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT));
155            }
156        });
157    }


主要工作是设置了 Apn 、运营商、用户代理信息加载器。

在 com/android/messaging/mmslib 包下面有一个pdu包和util包;

在android/support/v7/mms 包下面也有一个pdu包以及 ApnSettingsLoader, MmsManager, MmsService 等类。对比发现两个 pdu 包的内容大致相同,不知为啥要放两处。

我们来看一下 android/support/v7/ 包下的几个类,

ApnSettingsLoader // 为默认 SMS SIM 加载 APN 提供接口

ApnsXmlParser // 内置 APN 列表 XML 资源文件解析器(MmsXmlResourceParser的子类)

CarrierConfigValuesLoader // 运营商配置加载器

CarrierConfigXmlParser // 运营商配置解析器 (比如 mms_config)(MmsXmlResourceParser的子类)

DefaultApnSettingsLoader // 默认 APN 配置加载器

DefaultCarrierConfigValuesLoader // 默认运营商配置加载器

DefaultUserAgentInfoLoader // 默认 UA, UAProfUrl加载器

UserAgentInfoLoader // UA, UAProfUrl加载器

DownloadRequest // MMS 下载请求(MmsRequest的子类)

MmsHttpClient // MMS 发送和下载使用的 HTTP client

MmsHttpException // HTTP 异常

MmsManager // MMS 库的公开接口

MmsNetworkException // MMS 网络异常

MmsNetworkManager // 在 L 之前的设备使用废弃的 API(从Android L开始废弃)管理 MMS 网络连接(或者被强制使用在 L 或以后的平台)

MmsRequest // MMS 请求的基类, 它会处理所有的 MMS 请求的执行;

MmsService // 在 L 之前的平台使用废弃的 API 执行 MMS 请求的 Service

MmsXmlResourceParser // XML 解析器基类

PhoneNumberHelper // 电话号码格式帮助类,使用了独立的类( com.google.i18n.PhoneNumberUtil 类),因为它依赖 libphonenumber

SendRequest // 发送 MMS 请求

Utils // 工具类

其中 MmsManager 会直接调用 framework层的 android.telephony.SmsManager来收发彩信。

APN简介

一般在手机设置的移动网络设置 - 接入点名称(APN)选项可以查看 APN 的信息,并进行新建、重置等操作。

APN包含的信息如下:名称、APN、代理、端口、用户名、密码、服务器、MMSC、彩信代理、彩信端口、MCC、MNC、身份验证类型、APN类型、APN协议、APN漫游协议、承载系统、MVNO系统、MVNO值、PPP拨叫号码;

来看一下 apn 相关的类,

DefaultApnSettingsLoader 提供了从本地 xml(apns.xml) 和 system 读取 apn 信息的方法;

BugleApnSettingsLoader 提供了从 system 和本地数据库(apn.db)读取 apn 信息的方法;

获取 apn name的方法如下:(MmsNetworkManager.java)

244    public String getApnName() {
245        Network network = null;
246        synchronized (this) {
247            if (mNetwork == null) {
248                return null;
249            }
250            network = mNetwork;
251        }
252        String apnName = null;
253        final ConnectivityManager connectivityManager = getConnectivityManager();
254        final NetworkInfo mmsNetworkInfo = connectivityManager.getNetworkInfo(network);
255        if (mmsNetworkInfo != null) {
256            apnName = mmsNetworkInfo.getExtraInfo();
257        }
258        return apnName;
259    }


CarrierConfig简介

运营商配置包含了很多短信及彩信的配置,比如是否启用彩信、是否启用短信分组、超长短信是否分条发送等。

CarrierConfigValuesLoader 接口定义了运营商配置的key以及默认值;

DefaultCarrierConfigValuesLoader 类提供了从本地 xml(mms_config.xml) 和 system 读取 mms 配置信息的方法;

BugleCarrierConfigValuesLoader 类同样提供了从本地 xml(mms_config.xml) 和 system 读取 mms 配置信息的方法;

UserAgent简介

UserAgentInfoLoader 接口用于加载用户代理和 UA Prof URL(用户代理简介地址)。

什么是UserAgent呢?它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

DefaultUserAgentInfoLoader 和 BugleUserAgentInfoLoader 都是默认从 TelephonyManager 获取 MmsUserAgent 和 MmsUAProfUrl,如果为空再取默认值。

PDU简介

我们再来看一下 pdu 包下的内容,

AcknowledgeInd // M-Acknowledge.ind PDU 延迟下载确认 PDU(GenericPdu 子类)

Base64 // Base64 编码工具类

CharacterSets // 字符集 (http://www.iana.org/assignments/character-sets/character-sets.xhtml

ContentType // 内容类型

DeliveryInd // M-Delivery.Ind Pdu 已发送彩信的发送状态报告PDU

EncodedStringValue // Encoded-string-value = Text-string | Value-length Char-set Text-string

GenericPdu // Pdu基类

InvalidHeaderValueException // 无效头部值异常

MmsException // Mms 客户端通用异常

MultimediaMessagePdu // 多媒体信息PDU(GenericPdu 子类)

NotificationInd // M-Notification.ind PDU 新的彩信提醒PDU(GenericPdu 子类)

NotifyRespInd // M-NofifyResp.ind PDU 消息接收完成回复Pdu(GenericPdu 子类)

PduBody // Pdu 主体

PduContentTypes // Pdu 内容类型

PduHeaders // Pdu头部

PduParser // Pdu 解析器

PduPart // Pdu 部分

QuotedPrintable //

ReadOrigInd // M-Read-Orig.ind MMS 代理中转站发送的阅读/删除报告Pdu(GenericPdu 子类)

ReadRecInd // M-ReadRec.ind pdu MMS客户端发送的阅读/删除报告Pdu(GenericPdu 子类)

RetrieveConf // M-Retrive.conf Pdu 确认收到Pdn(GenericPdu 子类)

SendConf // M-Send.conf 发送结果状态 Pdu(GenericPdu 子类)

SendReq // M-Send.req 发送请求(GenericPdu 子类)

上面的类一大半是 pdu 的实现类,每种类都对应一种 pdu,来看看什么是 PDU以及 PDU 的种类有哪些。(参考文章:MMS Protocol Overview

一个(T)PDU 是一个封装的二进制块。在 MMS 代理(MMSC)与 MMS 客户端的每一次交互都是使用 PDU 来组成 MMS 信息的。下面是消息的类型:

- M-Send.req: 发送请求

- M-Send.conf: MMSC 发送给 MMS 客户端的交互结果状态码

- M-Notification.ind: 从 MMSC 发送的 MMS 提醒,代表一个新消息的可用性以及消息内容的地址。

- M-NotifyResp.ind :收到 M-Notification.ind 通知后发送给 MMCS 的已下载消息接收通知。

- M-Retrieve.conf: 包含一条新的 MMS,在自动下载模式下同 M-NotifyResp.ind 一起告知已收到。

- M-Acknowledgement .ind: 用于 MMS 引擎告知一个延期下载。

- m-Forward.reg: 用于转发仍在MMS中继或MMSC(没有下载)的彩信。并不是所有的运营商都支持这一功能。

- m-Forward.conf: 转发请求的返回状态码。

- M-Delivery.ind: 已发送彩信的发送状态报告。通过发送或转发时生成的网络消息 id 来标识。这个 id 可以用来

映射原始发送的消息。在 TPDU 里的状态值包含了已发送消息的实际状态,如已过期,已获取,已拒绝,已延期,未识别,

不明确,被转发,未送达等。

- M-Read-Rec.ind: MMS 客户端发送的阅读/删除报告

- M-Read-Orig.ind: MMS 代理发送的阅读/删除报告。

发送彩信流程

1 构造一个 M-Send-req TPDU,确保必要的字段已设置,特别是收件人地址。

2 初始化一个与目标 MMSC 服务器交互的 HTTP POST 请求,并将该 TPDU 作为 post 数据发送。

3 当应用程序收到一个 M-Send.conf TPDU 回复,解析它的状态信息。如果结果是成功,应用程序可以获取到一个网络消息 ID,这个 ID 可以用于匹配一个已接收传送或者阅读报告。

接收彩信流程

设备会通过 Wap-Push 或者 SMS 收到一个 M-Notification.ind TPDU,应用程序可以有两种回复方式:立即/自动下载或延时下载。

1 立即/自动下载模式下,内容地址获取和信息下载使用 HTTP GET 请求进行;M-NotifyResp.ind 通过 HTTP post 请求发送给 MMSC 告知彩信已收到。

注意:如果接收确认未发送,有些 MMSC 服务器会重复发送通知 TPDU。

2 在延时下载模式下,M-NotifyResp.ind Pdn 会附加一个延时标记来告知接收方。

注意:对于延时下载,应用程序应该发送一个 M-Acknowledgement.ind PDU 而不是 M-NotifyResp.ind,如果应用程序不发送 M-Acknowledgement.ind PDU,在信息下载后原始信息的发送方将无法收到接收报告。

总结

1 本篇内容介绍了 MMS 类库,它调用了 framework 层的 SmsManager 为应用程序提供 MMS 支持。

2 相关内容包括 Apn、CarrierConfig、UserAgent 等配置信息的加载,以及彩信传送单元 Pdu。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android messaging mms