android 控件回执流程,Android telephony MMS 学习笔记

本文主要从以下几个方面来学习MMS在android系统中的处理:

(1)MMS初始化、

(2)MMS发送、

(3)MMS接收(包括push MMS接收和从MMSC中提取MMS内容)、

(4)MMS存储/删除等数据操作。

Android MMS基本知识点

一、MMS概述

MMS是在短消息业务基础上发展起来的一种消息业务,它可以用于传送文字、图片、动画、音频和视频等多媒体信息。MMS采用"存储转发"的技术,用户创建的信息能够自动、快速的在手机和手机之间传送;信息的传送仍然按接收方手机号码进行定位;当接收方关机或暂时不在服务区的情况下,信息将存储在多媒体消息中心(MMSC),直到能够正确送达为止。MMS消息服务要求一个WAP网关,一个数据传输网如电路交换网、GPRS或WCDMA网络,和一个多媒体消息中心(MMSC)。在目前,MMS业务主要是以WAP作承载,以短消息作提示通知,由MMS手机自动到多媒体消息中心(MMSC)去提取来实现的。

在android中,MMS主要的处理都在app层,在framework层中主要涉及MMS

pdu包的解析处理和发送和接受MMS时的网络处理。

MMS会使用telephony

framework部分的类,详细信息请参考《Android_telephony_framework》系列文档。

二、MMS相关Service

1. TransactionService

主要是通过相应的transaction来处理MMS的发送、接收等请求。TransactionService包含一个ServiceHandler

handler内部类,用来处理MMS相应事件。

handleMessage()方法用来处理各种请求,如处理EVENT_TRANSACTION_REQUEST事件,根据Transaction的类型为NOTIFICATION_TRANSACTION,创建NotificationTransaction类实例,并根据URI从mmssms.db中取出PDU包。

三、MMS相关receiver

1. PushReceiver

一个BroadcastReceiver,接受Intent.WAP_PUSH_RECEIVED_ACTION,启动TransactionService来传递对应的push数据。

当接受到Intent.WAP_PUSH_RECEIVED_ACTION消息后,创建一个ReceivePushTask并使用它的execute方法。在ReceivePushTask方法中,根据Pdu

MessageType类型,执行不同操作,如处理短信通知。

2. MmsSystemEventReceiver

接受Mms.Intents.CONTENT_CHANGED_ACTION、TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED和intent.ACTION_BOOT_COMPLETED。

四、MMS相关handler

1. SMSDispatcher

对SMS/MMS上报事件的处理,它有两个子类:GsmSMSDispatcher和CdmaSMSDispatcher,分别是GSMPhone和CdmaPhone的handler类。

2. WapPushOverSms

WapPushOverSms类虽然没有继承自handler类,但它的作用却实实在在的是一个handler类的作用,是它通过

SMSDispatcher的dispatch方法来实现的。该类的作用是把接收到的push

PDU包通过intent方式派送到应用模块的receiver处理。

五、MMS相关transaction

1. Transaction

继承自Observable类,是NotificationTransaction、ReadRecTransaction、RetrieveTransaction和SendTransaction的抽象类。它负责发信息的最后处理和收信息的最初处理。主要是负责发送信息和接收信息。它并不是真正的发送和接收信息。是由系统Frameworks里面来负责接收和发送信息。

它里面定义了二个方法getPdu(),sendPdu()这二个方法是从MMSC取彩信数据,和向MMSC发送数据。

它是对HttpUtils的一层包装。

2. NotificationTransaction

继承自Transaction类,并实现Runnable接口。主要处理MMS的notifications

(M-Notification.ind)消息,也就是push彩信通知消息。主要功能:

1)根据DownloadManager. mAutoDownload状态判断是否需要立即从MMSC中下载MMS内容。

2)发送GET请求给MMSC

3)获取M-Retrieve.conf数据并解析

4)保存接收到的MMS到inbox

5)删除M-Notification.ind信息

6)发送the M-NotifyResp.ind给MMSC(回执信息)

7)处理完成后通知TransactionService做相应处理。

3.ReadRecTransaction

继承自Transaction类,并实现Runnable接口。主要处理MMS的read report notifications

(M-read-rec.ind)。主要功能:

1)Loads the read report indication from storage (Outbox).

即从mmssms.db中取出read report indication pdu。

2)Packs M-read-rec.ind and sends it.

3)Notifies the TransactionService about succesful completion.

4. RetrieveTransaction

继承自Transaction类,并实现Runnable接口。主要处理从MMSC中提取MMS(M-Retrieve.conf)。主要功能:

1)Sends a GET request to the MMSC server

2)Retrieves the binary M-Retrieve.conf data and parses it.

3)Persists the retrieve multimedia message.

4)Determines whether an acknowledgement is required.

5)Creates appropriate M-Acknowledge.ind and sends it to MMSC

server.

6)Notifies the TransactionService about succesful completion.

5. SendTransaction

继承自Transaction类,并实现Runnable接口。主要处理发送MMS到MMSC(M-Send.req)。主要功能:

1)Loads the multimedia message from storage

(Outbox).从OutBox读取彩信。

SendReq sendReq =

(SendReq) persister.load(mSendReqURI);

2)Packs M-Send.req and sends it.将彩信封装成请求信息(SendReq)并发送。

3)Retrieves confirmation data from the server (M-Send.conf).保存服务器返回的信息。

byte[] response =

sendPdu(SendingProgressTokenManager.get(tokenKey),

new PduComposer(mContext, sendReq).make());

4)Parses confirmation message and handles it.(检索返回信息确认发送成功)

SendConf conf = (SendConf) new

PduParser(response).parse();

5)Moves sent multimedia message from Outbox to

Sent.(将彩信从待发箱移动发件箱)

Uri uri = persister.move(mSendReqURI,

Sent.CONTENT_URI);

6)Notifies the TransactionService about successful

completion.(通知TransactionService完成发送。)

六、MMS相关provider

文件

类/接口名

超类/实现接口

说明

TelephonyProvider.java

TelephonyProvider

ContentProvider

APN、Proxy等信息的存取封装

MmsProvider.java

MmsProvider

ContentProvider

MMS的存取

MmsSmsProvider.java

MmsSmsProvider

ContentProvider

提供MMS和SMS统一的读取,不支持写操作

七、Framework中MMS相关类

包或分类

路径

说明

com.google.android.mms

frameworks\base\core\java\com\google\android\mms

MMS pdu包的通用content type类和MMS的异常处理类

com.google.android.mms.pdu

frameworks\base\core\java\com\google\android\mms\pdu

mms pdu包的解析处理类

com.google.android.mms.util

frameworks\base\core\java\com\google\android\mms\util

pdu包的存储类

android.provider

frameworks\base\core\java\android\provider

对应的provider所需要的数据封装类

android.net

frameworks\base\core\java\android\net

android.net.http

frameworks\base\core\java\android\net\http

com.google.android.mms

文件

类/接口名

超类/实现接口

说明

ContentType.java

ContentType

定义pdu包内容部分的所支持的元素类型,其中包括所支持的image、audio的类型

InvalidHeaderValueException.java

InvalidHeaderValueException

MmsException

对pdu header的异常处理,当header值无效时抛出

MmsException.java

MmsException

Exception

MMS异常接口类

com.google.android.mms.pdu

文件

类/接口名

超类/实现接口

说明

AcknowledgeInd.java

AcknowledgeInd

GenericPdu

M-Acknowledge.ind PDU,接受者发送给MMSC的确认消息

Base64.java

Base64

base64字符的解析处理

CharacterSets.java

CharacterSets

MMS编码类型

DeliveryInd.java

DeliveryInd

GenericPdu

M-Delivery.Ind Pdu,MMSC发送给发送者的送达报告

MultimediaMessagePdu.java

MultimediaMessagePdu

GenericPdu

Multimedia message PDU,MMS PDU实体类

NotificationInd.java

NotificationInd

GenericPdu

M-Notification.ind PDU,MMS push通知消息PDU

NotifyRespInd.java

NotifyRespInd

GenericPdu

M-NofifyResp.ind PDU,返回notification response 给MMSC

SendConf.java

SendConf

GenericPdu

M-Send.conf Pdu  ,MMSC返回给发送者的send

confirmation消息

PduBody.java

PduBody

处理pdu body部分

PduComposer.java

PduComposer

把对应的数据组成对应的MMS PDU包

PduHeaders.java

PduHeaders

解析MMS pdu header

PduParser.java

PduParser

MMS pdu包解析入口类

PduPersister.java

PduPersister

MMS pdu 存储管理类

RetrieveConf.java

RetrieveConf

MultimediaMessagePdu

M-Retrive.conf Pdu

SendReq.java

SendReq

MultimediaMessagePdu

M-Send.req pdu

com.google.android.mms.util

文件

类/接口名

超类/实现接口

说明

AbstractCache.java

AbstractCache

缓存处理抽象类

PduCache.java

PduCache

AbstractCache

PDU cache

PduCacheEntry.java

PduCacheEntry

PDU cache entry

SqliteWrapper.java

SqliteWrapper

Sqlite的Wrapper类,提供通过ContentResolver对象对相应的contentprovider类的对象做处理

android.provider

文件

类/接口名

超类/实现接口

说明

Telephony.java

Telephony

提供与SMS/MMS provider需要的数据和操作,包括对应的CONTENT_URI及其他一些数据

com.google.android.mms.util

com.google.android.mms.util

这两个包下的类主要是用来操作网络方面的。对于这方面,暂时还了解不多。

Android MMS基本处理

以下处理过程以GSMPhone为例。

一、MMS初始化

MMS的初始化基本上与SMS一致,只是在phoneApp初始化的过程中注册一些事件,如EVENT_NEW_SMS和

EVENT_NEW_SMS_STATUS_REPORT。在android平台中,MMS初始化的时候并没有信息数据的操作,android是以

sqlite3作为存储机制的,与MMS相关的所有数据都存储在mmssms.db文件中,此文件是会长期存在于手机中,不会被删除。对MMS的操作直接

就是对mmssms.db数据库的操作,所以在初始化部分对MMS数据没有做相应处理。下面详细的说明MMS初始化时的类的关系及事件注册过程:

1. GSMPhone的构造函数中创建GsmSMSDispatcher的实例mSMS :mSMS = new

GsmSMSDispatcher(this);

2.调用GsmSMSDispatcher构造函数,执行super(phone);由于GsmSMSDispatcher继承自SMSDispatcher类,实际执行了SMSDispatcher构造函数。

3.在SMSDispatcher的构造函数里,执行如下语句:

mCm = phone.mCM;//mCm是CommandsInterface接口类的对象

……………

mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);

……………

CommandsInterface类的setOnNewSMS方法中会创建Registrant类的实例mSMSRegistrant,用来保存

SMSDispatcher

handler对象、EVENT_NEW_SMS事件,在有新信息消息上报的时候,会通过mSMSRegistrant对象来获取

SMSDispatcher

handler对象,并把EVENT_NEW_SMS事件和相应的数据通过消息机制和handler处理机制发送给SMSDispatcher类的

handleMessage方法处理。

二、MMS接收

1. push MMS接收

MMS通知消息是以短信息PDU包的形式传递过来的(M-Notification.ind

PDU)。Android中的具体处理流程如下:

1)当有新信息来的时候,atchannel的reader线程会调用onUnsolicited()函数处理。

2)onUnsolicited()函数调用RIL_onUnsolicitedResponse()函数,并传入RIL_UNSOL_RESPONSE_NEW_SMS值及相应数据。

3)RIL_onUnsolicitedResponse()调用sendResponse()函数,通过socket(socket名:SOCKET_NAME_RIL)向ril.java层传递数据。

4)ril

java层通过RILReceiver接收器从socket中读出数据,处理后调用ril类中的processResponse()方法,processResponse()方法调用processUnsolicited()方法。

5)在processUnsolicited()方法中,执行下面语句:

case

RIL_UNSOL_RESPONSE_NEW_SMS: {

if

(RILJ_LOGD) unsljLog(response);

String a[] =

new String[2];

a[1] =

(String)ret;

SmsMessage

sms;

sms =

SmsMessage.newFromCMT(a); //根据SMS协议解析PDU包

if

(mSMSRegistrant != null) {

mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms,

null));

}

break;

其中mSMSRegistrant实例是在初始化的时候创建的,其中存储着SMSDispatcher

handler对象和EVENT_NEW_SMS事件信息。随后通过message消息机制和handler处理机制把EVENT_NEW_SMS事件传

递到了SMSDispatcher

handler类 处理。

6)SMSDispatcher

handler接收到EVENT_NEW_SMS事件,调用handleMessage()方法处理,handleMessage()方法调用其子类dispatchMessage()方法。

7)在dispatchMessage()中,根据smsHeader.portAddrs(PORT_WAP_PUSH =

2948)地址来判断是否是PUSH信息。

8)调用WapPushOverSms类的dispatchWapPdu()方法。

9)使用WspTypeDecoder类实例来对PUSH信息进行解析,并根据content type来判断是否是MMS

PUSH信息。

10)调用dispatchWapPdu_MMS()方法,通过SMSDispatcher类的dispatch()方法来广播发送intent.

WAP_PUSH_RECEIVED_ACTION。

11)PushReceiver接收到该intent,启动ReceivePushTas并执行doInBackground()方法。

12)在doInBackground()方法中,通过PduParser类对象解析对应的PDU包,然后执行如下代码:

case

MESSAGE_TYPE_NOTIFICATION_IND: {

NotificationInd nInd = (NotificationInd) pdu;

if

(!isDuplicateNotification(mContext, nInd)) {

Uri uri =

p.persist(pdu, Inbox.CONTENT_URI); //MMS PUSH信息存储在inbox.

Intent svc =

new Intent(mContext,

TransactionService.class);//intent启动的是TransactionService。

svc.putExtra(TransactionBundle.URI, uri.toString());

svc.putExtra(TransactionBundle.TRANSACTION_TYPE,

Transaction.NOTIFICATION_TRANSACTION);//transaction类型:NOTIFICATION_TRANSACTION

mContext.startService(svc);//启动TransactionService服务

}

13)TransactionService类中的onStart()调用launchTransaction()方法

14)launchTransaction()方法传递给ServiceHandler

EVENT_TRANSACTION_REQUEST事件。

15)ServiceHandler类的handleMessage()方法处理EVENT_TRANSACTION_REQUEST事件,根据

Transaction的类型为NOTIFICATION_TRANSACTION,创建NotificationTransaction类实例,并根据

URI从mmssms.db中取出PDU包。

16)调用processTransaction(transaction)方法,在processTransaction()方法中,执行如下代码:

int

connectivityResult =

beginMmsConnectivity();//通过beginMmsConnectivity函数进行data

connection。

if

(connectivityResult == Phone.APN_REQUEST_STARTED) {

//如果返回APN_REQUEST_STARTED结果,表示data

connection正在连接,等待返回EVENT_DATA_STATE_CHANGED事件

mPending.add(transaction);//把transaction放入等待队列中

return

true; //返回,等待EVENT_DATA_STATE_CHANGED事件再继续处理

}

transaction.attach(TransactionService.this); //因为Transaction

类和TransactionService

类都继承自Observable类,此处是为了Transaction类的子类在处理完成后通知TransactionService相应的处理结果。

transaction.process();

//进入NotificationTransaction类中处理,创建一个新的线程来处理该transaction。

17)下面的处理请参照MMS相关transaction中的NotificationTransaction说明。

2. 从MMSC中提取MMS

根据DownloadManager类中的mAutoDownload变量的值,从MMSC中提取MMS有两种情况:

1)如果mAutoDownload为TRUE,即允许自动提取,那么在indication通知上来的时候,就会从MMSC向提取MMS信息。即使在

NotificationTransaction中所做的处理。具体请参照MMS相关transaction中的

NotificationTransaction说明

2)否则,就需要手动去从MMSC中提取。具体处理如下:此时UI层会启动TransactionService,并传入

Transaction.RETRIEVE_TRANSACTION类型。其他的处理流程参考第一条(push

MMS接收)中的第13到第17步,只不过相应的transaction是RetrieveTransaction,而非

NotificationTransaction。

三、MMS发送

MMS的发送动作是由UI来触发的,主要是有ComposeMessageActivity类中的sendMmsWorker()方法来处理。具体处理流程如下:

1.

sendMmsWorker()方法中,创建MmsMessageSender类实例sender,并调用MmsMessageSender类中的sendMessage()方法。

2.从mmssms.db中取出对应的PDU数据,把信息移到outbox中(以前是存储在draft下),然后启动TransactionService服务进行transaction处理。

3.通过TransactionService处理进入了SendTransaction类的run()方法中处理。详细处理请参照MMS相关transaction中的SendTransaction说明

四、MMS存储/删除等数据操作

MMS信息的存储是以SQLite3为基础的,而且其mmssms.db数据库在第一次创建后会一直存在,这就对MMS的存储处理变得简单很多,只需要执行相应的SQL语句就行。

MMS中的内容部分是存储在file中的,并没有放在mmssms.db数据库中,数据库中存放的是如下几张表:

static final String TABLE_PDU =

"pdu";//PDU相关信息的表

static final String TABLE_ADDR = "addr";//MMS发件人/收件人地址相关的表

static final String TABLE_PART = "part";

//body可能分成几个部分,存储part相关信息的表,通过该part信息,就可以从file中取到对应的内容部分

static final String TABLE_RATE = "rate"; // SENT_TIME信息表

static final String TABLE_DRM = "drm";

上面的几张表只是存储了一些相关信息,通过它们可以取到相应的MMS的基本信息,并能从文件中读取到对应的MMS body。

对MMS存储机制的理解主要就是对content provider机制的理解,content

provider机制中主要涉及到以下类:

文件

类/接口名

超类/实现接口

说明

SQLiteDatabase.java

SQLiteDatabase

SQLiteClosable

SQLLite数据库实现类

SQLiteOpenHelper.java

SQLiteOpenHelper

管理数据库create、open、close、get,upgrade和版本信息的辅助类

ContentProvider.java

ContentProvider

实现不同应用对数据库的访问

ContentResolver.java

ContentResolver

ContentProvider的封装类,向application提供统一的访问接口,ContentProvider会根据URI来取得对应的ContentProvider对象

SqliteWrapper.java

SqliteWrapper

向application提供的ContentResolver类的封装类

MMS对应的数据库类:见MMS相关provider及Telephony、MmsSmsDatabaseHelper

五 MMS参数设置

MMS的参数设置也是通过SQLite3数据库进行操作的,其content

provider类:TelephonyProvider,其DatabaseHelper类是其内部类。TelephonyProvider对应的

CONTENT_URI在Telephony 类的Carriers内部类中。

MMS参数的设置主要在setting模块操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值