Android telephony MMS 學習筆記

本文主要從如下幾個方面來學習MMS在android系統中的處理:MMS初始化、MMS發送、MMS接收(包括push MMS接收和從MMSC中提取MMS內容)、MMS存儲/刪除等數據操做。 java

Android MMS基本知識點 android

1、MMS概述 sql

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》系列文檔。 網絡

2、MMS相關Service
1. TransactionService
主要是經過相應的transaction來處理MMS的發送、接收等請求。TransactionService包含一個ServiceHandler handler內部類,用來處理MMS相應事件。 app

3、MMS相關receiver
1. PushReceiver
接受Intent.WAP_PUSH_RECEIVED_ACTION,啓動TransactionService來傳遞對應的push數據。
2. MmsSystemEventReceiver
接受Mms.Intents.CONTENT_CHANGED_ACTION、TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED和intent.ACTION_BOOT_COMPLETED。 socket

4、MMS相關handler
1. SMSDispatcher
對SMS/MMS上報事件的處理,它有兩個子類:GsmSMSDispatcher和CdmaSMSDispatcher,分別是GSMPhone和CdmaPhone的handler類。
2. WapPushOverSms
WapPushOverSms類雖然沒有繼承自handler類,但它的做用卻實實在在的是一個handler類的做用,是它經過SMSDispatcher的dispatch方法來實現的。該類的做用是把接收到的push PDU包經過intent方式派送到應用模塊的receiver處理。 ide

5、MMS相關transaction
1. Transaction
繼承自Observable類,是NotificationTransaction、ReadRecTransaction、RetrieveTransaction和SendTransaction的抽象類。
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).
2)Packs M-Send.req and sends it.
3)Retrieves confirmation data from the server  (M-Send.conf).
4)Parses confirmation message and handles it.
5)Moves sent multimedia message from Outbox to Sent.
6)Notifies the TransactionService about successful completion. 函數

6、MMS相關provider

文件

類/接口名

超類/實現接口

說明

TelephonyProvider.java

TelephonyProvider

ContentProvider

APN、Proxy等信息的存取封裝

MmsProvider.java

MmsProvider

ContentProvider

MMS的存取

MmsSmsProvider.java

MmsSmsProvider

ContentProvider

提供MMS和SMS統一的讀取,不支持寫操做

7、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爲例。

1、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方法處理。

2、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。

3、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說明

4、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模塊操做。
相關文章
相關標籤/搜索