Android Mms專題之:接收資訊流程

來源:互聯網
上載者:User

資訊的接收工作是由底層來完成的,當有一個 新的資訊時底層完成接收後會以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也是只監聽資料庫的變化,一旦有變化立刻重新整理顯示資訊。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.