麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統(tǒng) > Android > 正文

Android Mms之:短信發(fā)送流程(圖文詳解)

2020-04-11 12:21:58
字體:
供稿:網(wǎng)友

信息的發(fā)送,對(duì)于Mms應(yīng)用程序來講主要就是在信息數(shù)據(jù)庫中創(chuàng)建并維護(hù)一條信息記錄,真正的發(fā)送過程交由底層(Frameworks層)函數(shù)來處理。

總體的來講,當(dāng)信息創(chuàng)建完成后,對(duì)于信息通常有三個(gè)去處,一個(gè)是放棄這個(gè)信息,也就是用戶不想要此信息,一旦選擇,信息將不會(huì)被保存;第二個(gè)去處就是保存為草稿;最后一個(gè)去處就是發(fā)送此信息。

當(dāng)點(diǎn)擊了發(fā)送后,UI層暫不會(huì)有變化,UI層要監(jiān)聽負(fù)責(zé)發(fā)送的各個(gè)類的回調(diào)信息和數(shù)據(jù)庫的變化信息來更新UI。信息發(fā)送的第一站是WorkingMessage,它會(huì)先處理一下信息的相關(guān)內(nèi)容,比如刷新收信人(Sync Recipients)以保證都是合法收信人,把附件(Slideshow)轉(zhuǎn)成可發(fā)送的彩信附件Pdu(SendReq),makeSendReq。然后針對(duì),不同的信息類型(短信,彩信)調(diào)用不同的處理類來處理。處理的流程也比較類似,都是先把消息放到一個(gè)隊(duì)列中,然后啟動(dòng)相應(yīng)的Service來處理。Service會(huì)維護(hù)信息隊(duì)列,然后處理每個(gè)信息。短信是由Frameworks中的SmsManager發(fā)送出去,而彩信是通過Http協(xié)議發(fā)送。

短信發(fā)送
在WorkingMessage拿到一個(gè)要發(fā)送的消息后,做了簡(jiǎn)單處理(刷新收信人),然后就會(huì)對(duì)短信和彩信彩取不同的處理流程。對(duì)于短信,WorkingMessage除了刷新聯(lián)系人外,不會(huì)再做其他的事情,它會(huì)創(chuàng)建SmsMessageSender并調(diào)用其sendMessage()方法來發(fā)送信息,相關(guān)的參數(shù)收信人地址(是以分號(hào)分隔的一串字符),信息內(nèi)容和所在對(duì)話的ID(thread id)在構(gòu)造SmsMessageSender對(duì)象是傳入的,構(gòu)造完成后,直接調(diào)用其sendMessage()方法即可,接下來SmsMessageSender會(huì)處理所有的事情。

在交由SmsMessageSender處理之前,WorkingMessage會(huì)回調(diào)UI一次,以讓UI刷新收信人編輯框和信息文本輸入框。

SmsMessageSender的主要任務(wù)就是,把信息進(jìn)行按收信人拆分,也就是說,短信是要給每個(gè)收信人都發(fā)一封,雖然你可能只編輯一個(gè)短信,但是當(dāng)收信人不只一個(gè)時(shí),就變成了多條短信,就要發(fā)出多條短信,要給每一個(gè)收信人都發(fā)一封短信。因此,SmsMessageSender的第一個(gè)任務(wù)就是分析收信人地址,得到收信人的個(gè)數(shù),然后把信息按每個(gè)收信人都放入待發(fā)送的隊(duì)列中。這樣就得到了一個(gè)短信發(fā)送隊(duì)列,短信的數(shù)目就是收信人的個(gè)數(shù)。事實(shí)上,SmsMessageSender的工作僅此而已,當(dāng)把信息都放入發(fā)送隊(duì)列后也就是寫進(jìn)數(shù)據(jù)庫,然后信息的狀態(tài)是正在發(fā)送中,它會(huì)發(fā)送Intent喚起SmsReceiverService來處理隊(duì)列,它的工作就完成了,sendMessage()也就此返回。SmsMessageSender的sendMessage()返回后,WorkingMessage會(huì)再次回調(diào)UI的接口,因?yàn)榇藭r(shí)短信已被寫入數(shù)據(jù)庫,所以UI會(huì)刷新信息列表,顯示剛剛的短信,這時(shí)的狀態(tài)應(yīng)該是正在發(fā)送中,因?yàn)槭菑拇l(fā)送隊(duì)列中拿到的。從這以后,發(fā)送流程的類不會(huì)再直接與UI進(jìn)行通信,發(fā)送服務(wù)SmsReceiverService等會(huì)直接更新數(shù)據(jù)庫中短信的狀態(tài),而UI會(huì)監(jiān)聽數(shù)據(jù)庫的變化,一旦信息數(shù)據(jù)發(fā)生變化,UI就會(huì)刷新列表中的消息,更新狀態(tài),比如將發(fā)送中變成已發(fā)送,或是標(biāo)明發(fā)送失敗等,而這些狀態(tài)都是發(fā)送服務(wù)在更新。

SmsReceiverService,不要被其名字虎住,它并不只負(fù)責(zé)接收信息,它是短信(SMS)處理的Service,負(fù)責(zé)短信的發(fā)送和接收,在得到發(fā)送短信息指令(ACTION_SEND_MESSAGE)后會(huì)從隊(duì)列中讀出第一個(gè)短信,然后創(chuàng)建SmsSingleRecipientSender對(duì)象,傳入收信人地址,消息內(nèi)容,所屬的threadid和短信的Uri,并調(diào)用其sendMessage()發(fā)送這個(gè)短信。

SmsSingleRecipientSender會(huì)調(diào)用SmsManager的方法divideMessage()來把短信分成適合發(fā)送的幾個(gè)部分,因?yàn)榭赡苄畔⑦^長,不能一次發(fā)送完成,所以就需要分成幾部分來分次發(fā)送。同時(shí)會(huì)把消息移動(dòng)到Outbox。然后會(huì)針對(duì)分割的每一部分都會(huì)創(chuàng)建二個(gè)PendingIntent,這二個(gè)PendingIntent都是給底層用的,一個(gè)用于當(dāng)短信被發(fā)送出去時(shí)廣播出來,另一個(gè)是在短信已被收信人接收到時(shí)廣播出來。所以二個(gè)廣播的作用是,一個(gè)可用于標(biāo)識(shí)短信已發(fā)送,另一個(gè)則可以作為送達(dá)的通知。最后調(diào)用SmsManager.sendMultipartTextMessage交由底層來發(fā)送短信。

SmsReceiverService并不是自己去監(jiān)聽SEND_MESSAGE_ACTION和MESSAGE_SENT_ACTION的,而是由SmsReceiver來監(jiān)聽這二個(gè)廣播事件,然后通過StartService再把這二個(gè)事件傳送給SmsReceiverService進(jìn)行處理。

信息已發(fā)送廣播和信息已送達(dá)廣播分別由SmsReceiverService監(jiān)聽和MessageStatusReceiver。它們收到廣播后,會(huì)從Intent中取得詳細(xì)的發(fā)送和送達(dá)狀態(tài),然后更新數(shù)據(jù)庫中信息的狀態(tài)(status),UI當(dāng)發(fā)現(xiàn)數(shù)據(jù)庫變化后,就會(huì)更新UI。

至此,一個(gè)短信發(fā)送完成。

彩信發(fā)送
彩信發(fā)送流程與短信不完全一致,WorkingMessage刷新收信人,生成彩信的可發(fā)送的Pdu―SendReq,接著會(huì)把彩信寫入數(shù)據(jù)庫,把要發(fā)送的SendReq也會(huì)寫入數(shù)據(jù)庫,后面會(huì)再從數(shù)據(jù)庫中讀取出SendReq,并標(biāo)識(shí)為草稿;然后會(huì)構(gòu)建MmsMessageSender,傳入收信人和彩信的Uri,讓其發(fā)送。這期間也會(huì)回調(diào)UI一次,以初始化收信人編輯框和信息編輯框。

MmsMessageSender先從數(shù)據(jù)庫中讀出彩信發(fā)送的Pdu―SendReq,Google的內(nèi)置包c(diǎn)om.google.android.mms.*;里面封裝了所有操作Pdu的方法,包括把Pdu寫入數(shù)據(jù)庫(PduPersister.persist()),從數(shù)據(jù)庫中讀取生成Pdu(PduPersister.load())。然后根據(jù)當(dāng)前彩信的配置和其他信息對(duì)SendReq進(jìn)行更新,比如設(shè)置Expiration,Priority,Date和Size等,把彩信移到Outbox,然后啟動(dòng)TransactionService來處理彩信。sendMessage()就此返回。WorkingMessage會(huì)再次回調(diào)UI的接口,因?yàn)榇藭r(shí)彩信已被在數(shù)據(jù)庫中,所以UI會(huì)刷新信息列表,顯示剛剛的彩信,這時(shí)的狀態(tài)應(yīng)該是正在發(fā)送中。

TransactionService,與短信的SmsReceiverService類似,是負(fù)責(zé)處理彩信的服務(wù),可以發(fā)送,接收等。對(duì)于TransactionService來講,所有的需要處理的流程,無論是發(fā)送還是接收,都是一個(gè)Transaction。它內(nèi)部有二個(gè)隊(duì)列,一個(gè)是當(dāng)前正在處理(processing)的Transaction,一個(gè)是待處理(pending)的Transaction。它維護(hù)這二個(gè)隊(duì)列,并檢查網(wǎng)絡(luò)的連接,打開彩信網(wǎng)絡(luò)連接,準(zhǔn)備和檢查環(huán)境,然后從待處理的隊(duì)列中取出第一個(gè),放入正在處理的隊(duì)列中,并處理這個(gè)Transaction,也就是調(diào)用Transaction.process()。

發(fā)送彩信是一個(gè)SendTransaction,它的process()方法負(fù)責(zé)發(fā)送彩信,它會(huì)創(chuàng)建一個(gè)獨(dú)立的線程來做,因此不會(huì)阻塞TransactionService,處理服務(wù)就可以再處理其他的Transaction。它會(huì)先從數(shù)據(jù)庫中取出彩信Pdu,M-Send.req,(SendReq),更新一些字段,比如date,然后調(diào)用其父類Transaction.java中的方法sendPdu來把SendReq發(fā)送出去,sendPdu()會(huì)返回發(fā)送的結(jié)果(send confirmation)。Transaction.sendPdu()會(huì)先設(shè)置好網(wǎng)路,然后直接調(diào)用HttpUtils中的httpConnection()方法,用HTTP把彩信發(fā)送出去,同時(shí)取得返回消息(Response)給SendTransaction。SendTransaction會(huì)檢查發(fā)送結(jié)果,返回結(jié)果(Send Confirmation),分析狀態(tài)并更新至數(shù)據(jù)庫(比如發(fā)送失敗或發(fā)送成功)。UI會(huì)監(jiān)聽到狀態(tài)變化,并更新信息列表。

到此,一個(gè)彩信發(fā)送完成。

前面有提到過TransactionSettings,它是對(duì)于一個(gè)處理流程的相關(guān)配置信息,里面含有MMSC(Multimedia Message Service Center),Proxy和ProxyPort。這些信息,特別對(duì)于發(fā)送和接收來說是十分重要的。因?yàn)閷?duì)于手機(jī)的信息,并不是手機(jī)直接把信息發(fā)送到接收人的手機(jī)上,而是直接發(fā)給服務(wù)中心,后面就是由服務(wù)中心再把信息發(fā)送給對(duì)應(yīng)的接收人的手機(jī)上。對(duì)于彩信也是這樣,HttpUtils通過HTTP協(xié)議把彩信發(fā)送給MMSC,它是一個(gè)URL地址,之后對(duì)于發(fā)送方來講,彩信就發(fā)送完了,彩信服務(wù)中心(MMSC)會(huì)處理接下來的發(fā)送過程,服務(wù)中心是與手機(jī)運(yùn)營相關(guān)的,它由運(yùn)營商來提供。對(duì)于Mms發(fā)送彩信,是不會(huì)特意指定TransactionSettings的,也就是說它不會(huì)指定MMSC和Proxy,那么TransactionService就會(huì)用系統(tǒng)默認(rèn)的MMSC,Proxy作為TranscationSetting,MMSC,Proxy和ProxyPort需要從Telephony數(shù)據(jù)庫中查詢出來,它們是與具體手機(jī)的APN設(shè)置和具體的運(yùn)營商相關(guān)。所以,這里如果想要改變彩信的配置信息,只能更改APN系統(tǒng)設(shè)置來完成。

而短信的發(fā)送就不涉及SMSC(短信服務(wù)中心),因?yàn)镕rameworks中的工具已經(jīng)封裝好了SmsManager提供了幾個(gè)發(fā)送短信的方法,可能它會(huì)去處理SMSC相關(guān)的東西。



總結(jié),可以看出數(shù)據(jù)庫在信息的發(fā)送過程中扮演了重要的角色,當(dāng)信息離開編輯器后就馬上寫入了數(shù)據(jù)庫,發(fā)送過程中的各個(gè)類都是先從數(shù)據(jù)庫中加載信息,然后做相應(yīng)處理,然后寫回?cái)?shù)據(jù)庫或是更新狀態(tài),然后再交由下一個(gè)流程來處理。而所謂的Pending Message Queue其實(shí)沒有相應(yīng)的數(shù)據(jù)結(jié)構(gòu),它們都是數(shù)據(jù)庫中的信息且狀態(tài)是待發(fā)送而已。所以信息離開編輯器后就被寫入了數(shù)據(jù)庫,只不過狀態(tài)一直在改變,從發(fā)送中到已發(fā)送,或發(fā)送失敗,或如果Telephony服務(wù)不可用會(huì)仍處在待發(fā)送,但對(duì)于UI頁面來講可能沒有那么多狀態(tài),它可能只顯示發(fā)送中,已發(fā)送和發(fā)送失敗。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产精品视频1区 | 国产91九色 | a网在线| 国产九九热视频 | 久久成人激情视频 | 日本黄色一级视频 | 免费毛片在线视频 | 久久精品一二三区白丝高潮 | 久久精品国产久精国产 | 黄色一级片在线观看 | 欧美在线观看视频一区二区 | av日韩在线免费观看 | 国产精品视频一区二区三区四区国 | 九九热精品视频在线 | 亚洲 91| 亚洲精品v天堂中文字幕 | 成年免费视频黄网站在线观看 | www.99re14.com| 免费在线观看成年人视频 | 成人444kkkk在线观看 | 亚洲精品v天堂中文字幕 | avlululu| 亚洲国产超高清a毛毛片 | 99国内精品| 亚洲精品无码不卡在线播放he | 孕妇体内谢精满日本电影 | 国产亚洲福利 | 精品xxxx户外露出视频 | 日本黄色大片免费 | 精品一区二区在线观看视频 | 中文日韩 | 国产91一区二区三区 | 国产999精品久久久久 | 在线成人免费观看视频 | 成人免费福利视频 | 久久九九热re6这里有精品 | 毛片视频免费观看 | 涩涩伊人 | 美女视频黄视大全视频免费网址 | 欧美18—19sex性hd | 国产精品美女久久久久久不卡 |