安卓軟件開發(fā)-零碎android網(wǎng)絡(luò)通信_(tái)第1頁(yè)
安卓軟件開發(fā)-零碎android網(wǎng)絡(luò)通信_(tái)第2頁(yè)
安卓軟件開發(fā)-零碎android網(wǎng)絡(luò)通信_(tái)第3頁(yè)
安卓軟件開發(fā)-零碎android網(wǎng)絡(luò)通信_(tái)第4頁(yè)
安卓軟件開發(fā)-零碎android網(wǎng)絡(luò)通信_(tái)第5頁(yè)
已閱讀5頁(yè),還剩72頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第七章Android網(wǎng)絡(luò)通信第七章Android網(wǎng)絡(luò)通信第七章Android網(wǎng)絡(luò)通信本章內(nèi)容Android平臺(tái)網(wǎng)絡(luò)通信AndroidHttp通信AndroidSocket通信AndroidSSL通信藍(lán)牙WIFI第七章Android網(wǎng)絡(luò)通信Android網(wǎng)絡(luò)通信AndroidSDK中一些與網(wǎng)絡(luò)有關(guān)的包如下所示:包描述

提供與網(wǎng)絡(luò)通信相關(guān)的類,包括流和數(shù)據(jù)包socket、Internet協(xié)議和常見HTTP處理。該包是一個(gè)多功能網(wǎng)絡(luò)資源。有經(jīng)驗(yàn)的Java開發(fā)人員可以立即使用這個(gè)熟悉的包創(chuàng)建應(yīng)用程序。java.io雖然沒有提供現(xiàn)實(shí)網(wǎng)絡(luò)通信功能,但是仍然非常重要。該包中的類由其他Java包中提供的socket和鏈接使用。它們還用于與本地文件的交互。java.nio包含表示特定數(shù)據(jù)類型的緩沖區(qū)的類。適用于兩個(gè)基于java語(yǔ)言的端點(diǎn)之間的通信。org.apache.*表示許多為HTTP通信提供精確控制和功能的包??梢詫pache視為流行的開源Web服務(wù)器。

除核心.*類以外,包含額外的網(wǎng)絡(luò)訪問(wèn)socket。該包包括URI類,后者頻繁用于Android應(yīng)用程序開發(fā),而不僅僅是傳統(tǒng)的聯(lián)網(wǎng)。.http包含處理SSL證書的類。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)網(wǎng)絡(luò)通信Android與服務(wù)器通信的方式一般有兩種:

http通信方式:httpURLConnetction接口、apache的接口——httpClient接口。http通信也分為post方式和get方式。

socket通信方式

第七章Android網(wǎng)絡(luò)通信Tcp連接要想明白Socket連接,先要明白TCP連接。手機(jī)能夠使用聯(lián)網(wǎng)功能是因?yàn)槭謾C(jī)底層實(shí)現(xiàn)了TCP/IP協(xié)議,可以使手機(jī)終端通過(guò)無(wú)線網(wǎng)絡(luò)建立TCP連接。TCP協(xié)議可以對(duì)上層網(wǎng)絡(luò)提供接口,使上層網(wǎng)絡(luò)數(shù)據(jù)的傳輸建立在“無(wú)差別”的網(wǎng)絡(luò)之上。

建立起一個(gè)TCP連接需要經(jīng)過(guò)“三次握手”:

第一次握手:客戶端發(fā)送syn包(syn=j)到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn);

第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);

第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成三次握手。

第七章Android網(wǎng)絡(luò)通信HTTP連接

HTTP協(xié)議即超文本傳送協(xié)議(HypertextTransferProtocol),是Web聯(lián)網(wǎng)的基礎(chǔ),也是手機(jī)聯(lián)網(wǎng)常用的協(xié)議之一,HTTP協(xié)議是建立在TCP協(xié)議之上的一種應(yīng)用。

HTTP連接最顯著的特點(diǎn)是客戶端發(fā)送的每次請(qǐng)求都需要服務(wù)器回送響應(yīng),在請(qǐng)求結(jié)束后,會(huì)主動(dòng)釋放連接。從建立連接到關(guān)閉連接的過(guò)程稱為“一次連接”。

1)在HTTP1.0中,客戶端的每次請(qǐng)求都要求建立一次單獨(dú)的連接,在處理完本次請(qǐng)求后,就自動(dòng)釋放連接。

2)在HTTP1.1中則可以在一次連接中處理多個(gè)請(qǐng)求,并且多個(gè)請(qǐng)求可以重疊進(jìn)行,不需要等待一個(gè)請(qǐng)求結(jié)束后再發(fā)送下一個(gè)請(qǐng)求。

由于HTTP在每次請(qǐng)求結(jié)束后都會(huì)主動(dòng)釋放連接,因此HTTP連接是一種“短連接”、“無(wú)狀態(tài)”,要保持客戶端程序的在線狀態(tài),需要不斷地向服務(wù)器發(fā)起連接請(qǐng)求。通常的做法是即使不需要獲得任何數(shù)據(jù),客戶端也保持每隔一段固定的時(shí)間向服務(wù)器發(fā)送一次“保持連接”的請(qǐng)求,服務(wù)器在收到該請(qǐng)求后對(duì)客戶端進(jìn)行回復(fù),表明知道客戶端“在線”。若服務(wù)器長(zhǎng)時(shí)間無(wú)法收到客戶端的請(qǐng)求,則認(rèn)為客戶端“下線”,若客戶端長(zhǎng)時(shí)間無(wú)法收到服務(wù)器的回復(fù),則認(rèn)為網(wǎng)絡(luò)已經(jīng)斷開。

第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http的工作方式

HTTP協(xié)議采用了請(qǐng)求/響應(yīng)的工作方式?;贖TTP1.0協(xié)議的客戶端在每次向服務(wù)器發(fā)出請(qǐng)求后,服務(wù)器就會(huì)向客戶端返回響應(yīng)消息(包括請(qǐng)求是否正確以及所請(qǐng)求的數(shù)據(jù)),在確認(rèn)客戶端已經(jīng)收到響應(yīng)消息后,服務(wù)端就會(huì)關(guān)閉網(wǎng)絡(luò)連接。在這個(gè)數(shù)據(jù)傳輸過(guò)程中,并不保存任何歷史信息和狀態(tài)信息,因此,HTTP協(xié)議也被認(rèn)為是無(wú)狀態(tài)的協(xié)議。

HTTP1.0通訊過(guò)程如圖所示:第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http的工作方式

HTTP1.1和HTTP1.0相比較而言,最大的區(qū)別就是增加了持久連接支持。當(dāng)客戶端使用HTTP1.1協(xié)議連接到服務(wù)器后,服務(wù)器就將關(guān)閉客戶端連接的主動(dòng)權(quán)交還給客戶端;也就是說(shuō),在客戶端向服務(wù)器發(fā)送一個(gè)請(qǐng)求并接收以一個(gè)響應(yīng)后,只要不調(diào)用Socket類的close方法關(guān)閉網(wǎng)絡(luò)連接,就可以繼續(xù)向服務(wù)器發(fā)送HTTP請(qǐng)求。HTTP1.1通訊過(guò)程如圖所示:第七章Android網(wǎng)絡(luò)通信SOCKET連接套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元。它是網(wǎng)絡(luò)通信過(guò)程中端點(diǎn)的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必須的五種信息(全相關(guān)):連接使用的協(xié)議,本地主機(jī)的IP地址,本地進(jìn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址,遠(yuǎn)地進(jìn)程的協(xié)議端口。

應(yīng)用層通過(guò)傳輸層進(jìn)行數(shù)據(jù)通信時(shí),TCP會(huì)遇到同時(shí)為多個(gè)應(yīng)用程序進(jìn)程提供并發(fā)服務(wù)的問(wèn)題。多個(gè)TCP連接或多個(gè)應(yīng)用程序進(jìn)程可能需要通過(guò)同一個(gè)TCP協(xié)議端口傳輸數(shù)據(jù)。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接,許多計(jì)算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應(yīng)用層可以和傳輸層通過(guò)Socket接口,區(qū)分來(lái)自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。

建立socket連接

建立Socket連接至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶端,稱為ClientSocket,另一個(gè)運(yùn)行于服務(wù)器端,稱為ServerSocket。第七章Android網(wǎng)絡(luò)通信SOCKET連接套接字之間的連接過(guò)程分為三個(gè)步驟:服務(wù)器監(jiān)聽,客戶端請(qǐng)求,連接確認(rèn)。

服務(wù)器監(jiān)聽:服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請(qǐng)求。

客戶端請(qǐng)求:指客戶端的套接字提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號(hào),然后就向服務(wù)器端套接字提出連接請(qǐng)求。

連接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽到或者說(shuō)接收到客戶端套接字的連接請(qǐng)求時(shí),就響應(yīng)客戶端套接字的請(qǐng)求,建立一個(gè)新的線程,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,雙方就正式建立連接。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請(qǐng)求。第七章Android網(wǎng)絡(luò)通信SOCKET連接與TCP連接創(chuàng)建Socket連接時(shí),可以指定使用的傳輸層協(xié)議,Socket可以支持不同的傳輸層協(xié)議(TCP或UDP),當(dāng)使用TCP協(xié)議進(jìn)行連接時(shí),該Socket連接就是一個(gè)TCP連接。

第七章Android網(wǎng)絡(luò)通信HTTP連接

HTTP連接使用的是“請(qǐng)求—響應(yīng)”的方式(2次握手),不僅在請(qǐng)求時(shí)需要先建立連接,而且需要客戶端向服務(wù)器發(fā)出請(qǐng)求后,服務(wù)器端才能回復(fù)數(shù)據(jù)。第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—什么是Http協(xié)議

HTTP協(xié)議是一種應(yīng)用層協(xié)議,HTTP是HyperTextTransferProtocol(超文本傳輸協(xié)議)的英文縮寫。HTTP可以通過(guò)傳輸層的TCP協(xié)議在客戶端和服務(wù)器之間傳輸數(shù)據(jù)。HTTP協(xié)議主要用于Web瀏覽器和Web服務(wù)器之間的數(shù)據(jù)交換。我們?cè)谑褂肐E或Firefox瀏覽網(wǎng)頁(yè)或下載Web資源時(shí),通過(guò)在地址欄中輸入,開頭的4個(gè)字母http就相當(dāng)于通知瀏覽器使用HTTP協(xié)議來(lái)和host所確定的服務(wù)器進(jìn)行通訊。

HTTP協(xié)議誕生于上世紀(jì)90年代初;第一個(gè)被廣泛使用的版本是HTTP0.9。在隨后的HTTP1.0中,增加了很多在HTTP0.9中沒有的特性;在最新的HTTP1.1中,對(duì)HTTP1.0做了更進(jìn)一步的改進(jìn);HTTP1.1將是HTTP協(xié)議的最后一個(gè)版本。想深入了解HTTP協(xié)議,請(qǐng)查看RFC2616或通過(guò)來(lái)了解HTTP協(xié)議的詳情。第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http1.1

HTTP1.1除了支持持久連接外,還將HTTP1.0的請(qǐng)求方法從原來(lái)的三個(gè)(GET、POST和HEAD)擴(kuò)展到了八個(gè)(OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT)。而且還增加了很多請(qǐng)求和響應(yīng)字段,如上述的持久連接的字段Connection。這個(gè)字段有兩個(gè)值,Close和Keep-Alive。如果使用Connection:Close,則關(guān)閉HTTP1.1的持久連接的功能,要打開HTTP1.1的持久連接的功能,必須使用Connection:Keep-Alive,或者不加Connection字段(因?yàn)镠TTP1.1在默認(rèn)情況下就是持久連接的)。

除了這些,還提供了身份認(rèn)證、狀態(tài)管理和緩存(Cache)等相關(guān)的請(qǐng)求頭和響應(yīng)頭。第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http協(xié)議的特點(diǎn)1.支持客戶/服務(wù)器模式;2.簡(jiǎn)單快速:客戶向服務(wù)器請(qǐng)求服務(wù)時(shí),只需傳送請(qǐng)求方法和路徑。請(qǐng)求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡(jiǎn)單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快;3.靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對(duì)象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記;4.無(wú)狀態(tài):HTTP協(xié)議是無(wú)狀態(tài)協(xié)議。無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快;第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http協(xié)議詳解[":"port][abs_path]http表示要通過(guò)HTTP協(xié)議來(lái)定位網(wǎng)絡(luò)資源;host表示合法的Internet主機(jī)域名或者IP地址;port指定一個(gè)端口號(hào),為空則使用缺省端口80;abs_path指定請(qǐng)求資源的URI;如果URL中沒有給出abs_path,那么當(dāng)它作為請(qǐng)求URI時(shí),必須以“/”的形式給出,通常這個(gè)工作瀏覽器自動(dòng)幫我們完成。例如:1、輸入:瀏覽器自動(dòng)轉(zhuǎn)換成:http:///http請(qǐng)求由三部分組成:請(qǐng)求行、消息報(bào)頭、請(qǐng)求正文。1)請(qǐng)求行:MethodRequest-URIHTTP-VersionCRLF其中Method表示請(qǐng)求方法;Request-URI是一個(gè)統(tǒng)一資源標(biāo)識(shí)符;HTTP-Version表示請(qǐng)求的HTTP協(xié)議版本;CRLF表示回車和換。第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http協(xié)議請(qǐng)求方法請(qǐng)求方法(所有方法全為大寫)有多種,各個(gè)方法的解釋如下:GET請(qǐng)求獲取Request-URI所標(biāo)識(shí)的資源;POST在Request-URI所標(biāo)識(shí)的資源后附加新的數(shù)據(jù);HEAD請(qǐng)求獲取由Request-URI所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭;PUT請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用Request-URI作為其標(biāo)識(shí);DELETE請(qǐng)求服務(wù)器刪除Request-URI所標(biāo)識(shí)的資源;TRACE請(qǐng)求服務(wù)器回送收到的請(qǐng)求信息,主要用于測(cè)試或診斷;CONNECT保留將來(lái)使用;OPTIONS請(qǐng)求查詢服務(wù)器的性能,或者查詢與資源相關(guān)的選項(xiàng)和需求。應(yīng)用舉例:GET方法:GET/form.htmlHTTP/1.1(CRLF)POST方法:POST/reg.jspHTTP/1.1(CRLF)第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http響應(yīng)2)HTTP響應(yīng)也是由三個(gè)部分組成:狀態(tài)行、消息報(bào)頭、響應(yīng)正文、狀態(tài)行格式如下:HTTP-VersionStatus-CodeReason-PhraseCRLF其中,HTTP-Version表示服務(wù)器HTTP協(xié)議的版本;Status-Code表示服務(wù)器發(fā)回的響應(yīng)狀態(tài)代碼;Reason-Phrase表示狀態(tài)代碼的文本描述。狀態(tài)代碼有三位數(shù)字組成,第一個(gè)數(shù)字定義了響應(yīng)的類別,且有五種可能取值:1xx:指示信息--表示請(qǐng)求已接收,繼續(xù)處理2xx:成功--表示請(qǐng)求已被成功接收、理解、接受3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作4xx:客戶端錯(cuò)誤--請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信—Http常見狀態(tài)碼描述常見狀態(tài)代碼、狀態(tài)描述、說(shuō)明:200OK//客戶端請(qǐng)求成功400BadRequest//客戶端請(qǐng)求有語(yǔ)法錯(cuò)誤,不能被服務(wù)器所理解401Unauthorized//請(qǐng)求,這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)//頭域一起使用403Forbidden//服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù)404NotFound//請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的URL500InternalServerError//服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤503ServerUnavailable//服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后,//可能恢復(fù)正常eg:HTTP/1.1200OK(CRLF)第七章Android網(wǎng)絡(luò)通信AndroidHTTP通信--HttpClient實(shí)例在表單提交中Get和POST主要有以下五種區(qū)別:1.get是從服務(wù)器上獲取數(shù)據(jù),post是向服務(wù)器傳送數(shù)據(jù)。2.get是把參數(shù)數(shù)據(jù)隊(duì)列加到提交表單的ACTION屬性所指的URL中,值和表單內(nèi)各個(gè)字段一一對(duì)應(yīng),在URL中可以看到。post是通過(guò)HTTPpost機(jī)制,將表單內(nèi)各個(gè)字段與其內(nèi)容放置在HTMLHEADER內(nèi)一起傳送到ACTION屬性所指的URL地址。用戶看不到這個(gè)過(guò)程。3.對(duì)于get方式,服務(wù)器端用

Request.QueryString獲取變量的值,對(duì)于post方式,服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)。4.get傳送的數(shù)據(jù)量較小,不能大于2KB。post傳送的數(shù)據(jù)量較大,一般被默認(rèn)為不受限制。但理論上,IIS4中最大量為80KB,IIS5中為100KB。5.get安全性非常低,post安全性較高。第七章Android網(wǎng)絡(luò)通信HttpClient—通過(guò)Get方式獲取請(qǐng)求數(shù)據(jù)

Android的Get方式首先要初始化

HttpClientclient=newDefaultHttpClient();

HttpGetrequest=newHttpGet();在初始化url地址是,可以預(yù)先定義一個(gè)字符串,在初始化HttpClient時(shí)作為構(gòu)造函數(shù)的參數(shù)輸入;亦可在創(chuàng)建好HttpGet的實(shí)例后,采用request.setURL()的方式設(shè)置地址。Get方式出了可以訪問(wèn)無(wú)參數(shù)的地址外也可帶參數(shù)訪問(wèn)。實(shí)例源碼見備注:其中g(shù)oogleWeatherUrl2可以為一個(gè)無(wú)參數(shù)的網(wǎng)絡(luò)地址,也可以是帶參數(shù)的網(wǎng)絡(luò)地址,在本例中/ig/api?hl=zh-cn&weather=chengdu,第七章Android網(wǎng)絡(luò)通信HttpClient—通過(guò)Post方式獲取請(qǐng)求數(shù)據(jù)很多情況下,需要通過(guò)POST將本地的數(shù)據(jù)發(fā)送給服務(wù)器,但是post方式比get方式要復(fù)雜。首先要通過(guò)HttpPost來(lái)構(gòu)建一個(gè)post請(qǐng)求。方式如下:HttpPosthttppost=newHttpPost(url);另外需要使用NameValuePair來(lái)保存客戶端傳遞的參數(shù),可以使用BasicNameValuePair來(lái)構(gòu)造一個(gè)要被傳遞的參數(shù),通過(guò)add方法把這些參數(shù)加入到NameValuePair中,代碼為:List<NameValuePair>params=newArrayList<NameValuePair>();params.add(newBasicNameValuePair(valuename,value));其他的方式post方式與get方式?jīng)]有多大差別,可以通過(guò)HttpClient來(lái)請(qǐng)求連接,返回并響應(yīng)處理。實(shí)例源碼見備注第七章Android網(wǎng)絡(luò)通信HttpClient實(shí)例運(yùn)行結(jié)果展示注意,要在AndroidManifest.xml中加入<uses-permissionandroid:name="android.permission.INTERNET"/>允許用戶訪問(wèn)網(wǎng)絡(luò)。運(yùn)行時(shí)的初始狀態(tài)Get方式Post方式第七章Android網(wǎng)絡(luò)通信AndroidURL通信Java網(wǎng)絡(luò)編程熟悉的人,肯定不會(huì)對(duì)HttpURLConnection陌生,HttpURLConnection屬于JavaAPI的標(biāo)準(zhǔn)接口,包含在包.*中。Android平臺(tái)的網(wǎng)絡(luò)應(yīng)用絕大部分都是基于Java的編程接口的,也就是說(shuō)我們開發(fā)類似的運(yùn)用的時(shí)候可以有多種選擇,比J2me確實(shí)好多了。在Android中除了使用WebView控件訪問(wèn)網(wǎng)絡(luò)以外,還有用代碼方式訪問(wèn)網(wǎng)絡(luò)的方法,代碼方式有時(shí)候會(huì)顯得更加靈活。本節(jié)介紹使用URLConnection對(duì)象和HttpClient組件訪問(wèn)網(wǎng)絡(luò)的方法。而這兩種方法和JavaWeb開發(fā)中的使用方式幾乎沒有區(qū)別,而Web開發(fā)的相關(guān)資料比比皆是,因此有興趣的同學(xué)學(xué)完本講之后可以專門去研究一下HttpClient4.0的內(nèi)容,以求更深入的學(xué)習(xí)。第七章Android網(wǎng)絡(luò)通信AndroidURL通信下面提供了訪問(wèn)HTTP服務(wù)的基本功能。使用這部分接口的基本操作主要包括:

第一,創(chuàng)建URL以及HttpURLConnection對(duì)象。

第二,連接參數(shù)設(shè)置。

第三,連接到服務(wù)器。

第四,向服務(wù)器寫數(shù)據(jù)。

最后一步,從服務(wù)器讀取數(shù)據(jù)。URL的使用方法如下面的代碼,見備注。第七章Android網(wǎng)絡(luò)通信AndroidURL通信其中URL的通信方式也可以分別采用前面章節(jié)介紹過(guò)的Post和Get兩種方式來(lái)實(shí)現(xiàn)。HttpURLConnection是java的標(biāo)準(zhǔn)類,繼承自URLConnection類,URLConnection與HttpURLConnection都是抽象類,無(wú)法直接實(shí)例化對(duì)象。其對(duì)象主要通過(guò)URL的openConnection方法獲得,創(chuàng)建一個(gè)httpURLConnection連接的代碼如下所示:URLurl=newUR(“”);HttpURLConnectionurlConn=(HttpURLConnection)url.openConnection();

openConnection方法只創(chuàng)建URLConnection或者HttpURLConnection實(shí)例,但是并不進(jìn)行真正的連接操作。并且,每次openConnection都將創(chuàng)建一個(gè)新的實(shí)例。因此,在連接之前我們可以對(duì)其一些屬性進(jìn)行設(shè)置,比如超時(shí)時(shí)間等。第七章Android網(wǎng)絡(luò)通信AndroidURL通信下面對(duì)HttpURLConnetcion實(shí)例的屬性設(shè)置://設(shè)置輸入/輸出流connection.setDoOutput(true);connection.setDoInput(true);//設(shè)置請(qǐng)求的方式為Get或者Postconnection.setRequestMethod(“GET”);connection.setRequestMethod(“POST”);//在設(shè)置POST方式時(shí)要注意,POST請(qǐng)求方式不能夠使用緩存connection.setUseCaches(false);在完成HttpURLConnection實(shí)例的初始化以后,我們可以分別使用Get和POST方式來(lái)完成一個(gè)實(shí)例。第七章Android網(wǎng)絡(luò)通信AndroidURL通信實(shí)例—布局文件在該實(shí)例中Android設(shè)備的主界面主要包括一個(gè)靜態(tài)文本框,兩個(gè)按鈕以及一個(gè)文本框用來(lái)顯示請(qǐng)求返回的數(shù)據(jù)結(jié)果。整個(gè)Activity的布局如下:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android=""android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/TextView01"android:text="網(wǎng)絡(luò)連接測(cè)試"></TextView><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/Button01"android:text="使用URLConnectionGet訪問(wèn)GoogleWeatherAPI"></Button><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/Button02"android:text="使用URLConnectionpost訪問(wèn)GoogleWeatherAPI"></Button><ScrollViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/ScrollView01"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/TextView02"></TextView></ScrollView></LinearLayout>第七章Android網(wǎng)絡(luò)通信AndroidURL通信實(shí)例—Get方式Get用于獲取靜態(tài)頁(yè)面,只要把參數(shù)寫在URL后面即可傳送數(shù)據(jù)。一般只需要?jiǎng)?chuàng)建一個(gè)HttpURLConnection:URLurl=newURL();HttpURLConnectionurlConn=(HttpURLConnection)url.openConnection();注意:HttpURLConnection是Java的標(biāo)準(zhǔn)類,繼承自URLConnection類,兩者都是抽象類,無(wú)法進(jìn)行實(shí)例化對(duì)象。其對(duì)象主要通過(guò)URL的openConnection方法獲得采用get方式的HttpURLConnetction實(shí)例源碼見備注:此外,還需在AndroidManifest.xml中配置:<uses-permissionandroid:name=“android.permission.INTERNET”/>第七章Android網(wǎng)絡(luò)通信AndroidURL通信實(shí)例—Post方式在Post中,openConnection方法只創(chuàng)建了URLConnection或者HttpURLConnection實(shí)例,但是并不進(jìn)行真正的連接操作。并且,每次openConnection都將創(chuàng)建一個(gè)新的實(shí)例。因此,連接之前我們需要對(duì)其一些屬性進(jìn)行操作,比如超過(guò)時(shí)間等。下面是對(duì)HttpURLConnection實(shí)例的屬性設(shè)置://設(shè)置輸入(輸出)流connection.setDoOutput(true);connection.setDoInput(true);//設(shè)置方式為POSTconnection.setRequestMethod("POST");//Post請(qǐng)求不能使用緩存connection.setUseCaches(false);//關(guān)閉HttpURLConnection連接urlConn.disconnect();采用post方式的HttpURLConnetction實(shí)例源碼見備注:第七章Android網(wǎng)絡(luò)通信AndroidURL通信實(shí)例效果圖URL通信的Get方式和Post方式效果圖如下:運(yùn)行時(shí)的初始狀態(tài)Get方式Post方式第七章Android網(wǎng)絡(luò)通信Android套接字(Socket)通信什么是套接字(Socket)?

NetworkAPI是典型的用于基于TCP/IP網(wǎng)絡(luò)Java程序與其他程序通訊,NetworkAPI依靠Socket進(jìn)行通訊。Socket可以看成在兩個(gè)程序進(jìn)行通訊連接中的一個(gè)端點(diǎn),一個(gè)程序?qū)⒁欢涡畔懭隨ocket中,該Socket將這段信息發(fā)送給另外一個(gè)Socket中,使這段信息能傳送到其他程序中,如圖:第七章Android網(wǎng)絡(luò)通信Android套接字(Socket)通信

分析一下上圖,HostA上的程序A將一段信息寫入Socket中,Socket的內(nèi)容被HostA的網(wǎng)絡(luò)管理軟件訪問(wèn),并將這段信息通過(guò)HostA的網(wǎng)絡(luò)接口卡發(fā)送到HostB,HostB的網(wǎng)絡(luò)接口卡接收到這段信息后,傳送給HostB的網(wǎng)絡(luò)管理軟件,網(wǎng)絡(luò)管理軟件將這段信息保存在HostB的Socket中,然后程序B才能在Socket中閱讀這段信息。

假設(shè)在圖中的網(wǎng)絡(luò)中添加第三個(gè)主機(jī)HostC,那么HostA怎么知道信息被正確傳送到HostB而不是被傳送到HostC中了呢?

基于TCP/IP網(wǎng)絡(luò)中的每一個(gè)主機(jī)均被賦予了一個(gè)唯一的IP地址。每一個(gè)基于TCP/IP網(wǎng)絡(luò)通訊的程序都被賦予了唯一的端口和端口號(hào),端口是一個(gè)信息緩沖區(qū),用于保留Socket中的輸入/輸出信息,端口號(hào)是一個(gè)16位無(wú)符號(hào)整數(shù),范圍是0-65535,以區(qū)別主機(jī)上的每一個(gè)程序(端口號(hào)就像房屋中的房間號(hào)),低于256的短口號(hào)保留給標(biāo)準(zhǔn)應(yīng)用程序。第七章Android網(wǎng)絡(luò)通信Android套接字(Socket)通信—Socket類兩個(gè)常用的構(gòu)造函數(shù)是

Socket(InetAddressaddr,intport)和

Socket(Stringhost,intport),兩個(gè)構(gòu)造函數(shù)都創(chuàng)建了一個(gè)基于Socket的連接服務(wù)器端流套接字的流套接字。對(duì)于第一個(gè)InetAddress子類對(duì)象通過(guò)addr參數(shù)獲得服務(wù)器主機(jī)的IP地址,對(duì)于第二個(gè)函數(shù)host參數(shù)包被分配到InetAddress對(duì)象中,如果沒有IP地址與host參數(shù)相一致,那么將拋出UnknownHostException異常對(duì)象。兩個(gè)函數(shù)都通過(guò)參數(shù)port獲得服務(wù)器的端口號(hào)。如果創(chuàng)建了一個(gè)Socket對(duì)象,那么它可能通過(guò)調(diào)用Socket的

getInputStream()方法從服務(wù)程序獲得輸入流讀傳送來(lái)的信息,也可能通過(guò)調(diào)用Socket的

getOutputStream()方法獲得輸出流來(lái)發(fā)送消息。第七章Android網(wǎng)絡(luò)通信Android套接字(Socket)通信—Socket類下面我們將示范一個(gè)流套接字的客戶程序,這個(gè)程序?qū)?chuàng)建一個(gè)Socket對(duì)象,Socket將訪問(wèn)運(yùn)行在指定主機(jī)端口10000上的服務(wù)程序,如果訪問(wèn)成功客戶程序?qū)⒔o服務(wù)程序發(fā)送一系列命令并打印服務(wù)程序的響應(yīng)。

SSClient的源代碼見備注:運(yùn)行這段程序?qū)?huì)得到下面的結(jié)果:TueJan2918:11:51CST2002

TUESDAY

29

29第七章Android網(wǎng)絡(luò)通信Android套接字(Socket)通信—Socket類在SSClient源代碼編譯完成后,可以輸入javaSSClient來(lái)執(zhí)行這段程序,如果有合適的程序運(yùn)行在不同的主機(jī)上,采用主機(jī)名/IP地址為參數(shù)的輸入方式,比如是運(yùn)行服務(wù)器程序的主機(jī),那么輸入方式就是javaSSClient。技巧

Socket類包含了許多有用的方法。比如getLocalAddress()將返回一個(gè)包含客戶程序IP地址的InetAddress子類對(duì)象的引用;getLocalPort()將返回客戶程序的端口號(hào);getInetAddress()將返回一個(gè)包含服務(wù)器IP地址的InetAddress子類對(duì)象的引用;getPort()將返回服務(wù)程序的端口號(hào)第七章Android網(wǎng)絡(luò)通信Android套接字編程實(shí)例a)創(chuàng)建Socket的方法:Socket(InetAddressremoteAddress,intremotePort)利用Socket的構(gòu)造函數(shù),可以創(chuàng)建一個(gè)TCP套接字后,先連接到指定的遠(yuǎn)程地址和端口號(hào)。b)操作Socket的方法InputStreamgetInputStream()OutputStreamgetOutputStream()voidclose()操作TCPsocket的圖如下所示:第七章Android網(wǎng)絡(luò)通信Android套接字通信—ServerSocket類由于SSClient使用了流套接字,所以服務(wù)程序也要使用流套接字。這就要?jiǎng)?chuàng)建一個(gè)ServerSocket對(duì)象,ServerSocket有幾個(gè)構(gòu)造函數(shù),最簡(jiǎn)單的是ServerSocket(intport),當(dāng)使用ServerSocket(intport)創(chuàng)建一個(gè)ServerSocket對(duì)象,port參數(shù)傳遞端口號(hào),這個(gè)端口就是服務(wù)器監(jiān)聽連接請(qǐng)求的端口,如果在這時(shí)出現(xiàn)錯(cuò)誤將拋出IOException異常對(duì)象,否則將創(chuàng)建ServerSocket對(duì)象并開始準(zhǔn)備接收連接請(qǐng)求。接下來(lái)服務(wù)程序進(jìn)入無(wú)限循環(huán)之中,無(wú)限循環(huán)從調(diào)用ServerSocket的accept()方法開始,在調(diào)用開始后accept()方法將導(dǎo)致調(diào)用線程阻塞直到連接建立。在建立連接后accept()返回一個(gè)最近創(chuàng)建的Socket對(duì)象,該Socket對(duì)象綁定了客戶程序的IP地址或端口號(hào)。第七章Android網(wǎng)絡(luò)通信Android套接字編程實(shí)例

ServerSocket:這個(gè)類是實(shí)現(xiàn)了一個(gè)服務(wù)器端的Socket,利用這個(gè)類可以監(jiān)聽來(lái)自網(wǎng)絡(luò)的請(qǐng)求。a)創(chuàng)建ServerSocket的方法:ServerSocket(IntlocalPort)ServerSocket(intlocalport,intqueueLimit)ServerSocket(intlocalport,intqueueLimit,InetAddresslocalAddr)創(chuàng)建一個(gè)ServerSocket必須指定一個(gè)端口,以便客戶端能夠向該端口號(hào)發(fā)送連接請(qǐng)求。端口的有效范圍是0-65535b)ServerSocket操作Socket.accept()voidcloseaccept()方法為下一個(gè)傳入的連接請(qǐng)求創(chuàng)建Socket實(shí)例,并將已成功連接的Socket實(shí)例返回給服務(wù)器套接字,如果沒有連接請(qǐng)求,accept()方法將阻塞等待;close方法用于關(guān)閉套接字第七章Android網(wǎng)絡(luò)通信Android套接字通信—ServerSocket類為了示范我們?cè)谏厦嬲劦降目畈⑼瓿蒘SClient程序,下面我們創(chuàng)建一個(gè)SSServer程序,程序?qū)?chuàng)建一個(gè)ServerSocket對(duì)象來(lái)監(jiān)聽端口10000的連接請(qǐng)求,如果成功服務(wù)程序?qū)⒌却B接輸入,開始一個(gè)線程處理連接,并響應(yīng)來(lái)自客戶程序的命令。

這段程序的代碼見備注。運(yùn)行這段程序?qū)⒌玫较旅娴妮敵觯篠erverstarting...

AcceptingConnection...

ClosingConnection...第七章Android網(wǎng)絡(luò)通信Android套接字編程實(shí)例基于TCP的Socket實(shí)例的Server端和Client端的代碼見備注。Activity的布局文件main.xml為:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android=""android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/text"></TextView><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/button"android:text="連接服務(wù)器"></Button></LinearLayout>第七章Android網(wǎng)絡(luò)通信Android套接字編程實(shí)例需要注意的是需要在AndroidMainfest.xml文件中加入一行允許用戶訪問(wèn)網(wǎng)絡(luò)的代碼:<uses-permissionandroid:name="android.permission.INTERNET"></uses-permission>服務(wù)器端初始狀態(tài)客戶端初始狀態(tài)運(yùn)行時(shí)服務(wù)器狀態(tài)運(yùn)行時(shí)客戶端狀態(tài)第七章Android網(wǎng)絡(luò)通信Android套接字通信—數(shù)據(jù)報(bào)套接字使用流套接字的每個(gè)連接均要花費(fèi)一定的時(shí)間,要減少這種開銷,網(wǎng)絡(luò)API提供了第二種套接字:自尋址套接字(datagramsocket),數(shù)據(jù)報(bào)使用UDP發(fā)送尋址信息(從客戶程序到服務(wù)程序或從服務(wù)程序到客戶程序),不同的是可以通過(guò)數(shù)據(jù)報(bào)套接字發(fā)送多IP信息包,數(shù)據(jù)報(bào)信息包含在自尋址包中,此外自尋址包又包含在IP包內(nèi),這就將尋址信息長(zhǎng)度限制在60000字節(jié)內(nèi)。圖4顯示了位于IP包內(nèi)的數(shù)據(jù)報(bào)包的自尋址信息。第七章Android網(wǎng)絡(luò)通信Android套接字通信—數(shù)據(jù)報(bào)套接字?jǐn)?shù)據(jù)報(bào)套接字工作包括下面三個(gè)類:DatagramPacket,DatagramSocket,和MulticastSocket。DatagramPacket對(duì)象描繪了數(shù)據(jù)報(bào)包的地址信息,DatagramSocket表示客戶程序和服務(wù)程序數(shù)據(jù)報(bào)套接字,MulticastSocket描繪了能進(jìn)行多點(diǎn)傳送的數(shù)據(jù)報(bào)套接字,這三個(gè)類均位于包內(nèi)。在使用數(shù)據(jù)報(bào)之前,你需要首先熟悉DatagramPacket類,地址信息和數(shù)據(jù)報(bào)以字節(jié)數(shù)組的方式同時(shí)壓縮入這個(gè)類創(chuàng)建的對(duì)象中。

DatagramPacket有數(shù)個(gè)構(gòu)造函數(shù),即使這些構(gòu)造函數(shù)的形式不同,但通常情況下他們都有兩個(gè)共同的參數(shù):byte[]buffer和intlength,buffer參數(shù)包含了一個(gè)對(duì)保存數(shù)據(jù)報(bào)信息的字節(jié)數(shù)組的引用,length表示字節(jié)數(shù)組的長(zhǎng)度。第七章Android網(wǎng)絡(luò)通信使用基于UDP的Socketa)創(chuàng)建DatagramPacketDatagramSocket(byte[]data,intoffset,intlength,InetAddressremoteAddr,intremotePort)該構(gòu)造函數(shù)創(chuàng)建一個(gè)數(shù)據(jù)報(bào)文對(duì)象,數(shù)據(jù)包含在第一個(gè)參數(shù)當(dāng)中b)創(chuàng)建DatagramSocket創(chuàng)建DatagramSocket(intlocalPort)以上構(gòu)造函數(shù)將創(chuàng)建一個(gè)UDP套接字;c)DatagramSocket:發(fā)送和接受voidsend(DatagramPacketpacket)voidreceive(DatagramPacketpacket)send()方法用來(lái)發(fā)送DatagramPacket實(shí)例。一旦創(chuàng)建連接,數(shù)據(jù)報(bào)將發(fā)送到該套接字所連接的地址;receive()方法將阻塞等待,知道接收到數(shù)據(jù)報(bào)文,并將報(bào)文中的數(shù)據(jù)復(fù)制到指定的DatagramPacket實(shí)例中。對(duì)AndroidManifest.xml的配置一定不要忘了:<uses-permissionandroid:name="android.permission.INTERNET"/>編程方式跟Tcp方式一樣,有興趣的同學(xué)可以去嘗試實(shí)現(xiàn)。第七章Android網(wǎng)絡(luò)通信AndroidSSL通信AndroidSSL通信模式:Android平臺(tái)下的應(yīng)用開發(fā)采用JAVA語(yǔ)言,在Android提供的默認(rèn)類庫(kù)中,.ssl類庫(kù)包實(shí)現(xiàn)了通用的SSL功能。具體實(shí)現(xiàn)時(shí),只需將證書文件和CA信任列表load到對(duì)應(yīng)的KeyStore中,并用這些KeyStore初始化需要打開的SSLContext,然后建立連接,底層虛擬機(jī)就實(shí)現(xiàn)了單(雙)向握手過(guò)程,之后只要簡(jiǎn)單的使用BufferReader和BufferWriter就實(shí)現(xiàn)了SSL加密傳輸。Android的私鑰和信任證書的格式必須是BKS格式的,通過(guò)配置本地JDK,讓keytool可以生成BKS格式的私鑰和信任證書,java本身沒有BouncyCastle密庫(kù)

。為了實(shí)現(xiàn)消息認(rèn)證。Server需要:1)KeyStore:其中保存服務(wù)端的私鑰2)TrustKeyStore:其中保存客戶端的授權(quán)證書Clinet需要:1)KeyStore:其中保存客戶端的私鑰2)TrustKeyStore:其中保存服務(wù)端的授權(quán)證書第七章Android網(wǎng)絡(luò)通信AndroidSSL通信—服務(wù)端密鑰文件的生成使用java自帶的keytool命令,去生成這樣信息文件:1)生成服務(wù)端私鑰,并且導(dǎo)入到服務(wù)端KeyStore文件中2)根據(jù)私鑰,導(dǎo)出服務(wù)端證書3)將服務(wù)端證書,導(dǎo)入到客戶端的TrustKeyStore中第七章Android網(wǎng)絡(luò)通信AndroidSSL通信—客戶端密鑰文件的生成采用同樣的方法,生成客戶端的私鑰,客戶端的證書,并且導(dǎo)入到服務(wù)端的TrustKeyStore中。keytool-genkey-aliasclientkey-keystorekclient.keystorekeytool-export-aliasclientkey-keystorekclient.keystore-fileclient.crtkeytool-import-aliasclientkey-fileclient.crt-keystoretserver.keystore有興趣的同學(xué)可以參考備注里的客戶端和服務(wù)端實(shí)現(xiàn)的代碼,看看AndroidSSL通信的效果。第七章Android網(wǎng)絡(luò)通信Android藍(lán)牙通信—藍(lán)牙的基本知識(shí)藍(lán)牙(Bluetooth,亦譯作“藍(lán)芽”),是一種無(wú)線個(gè)人局域網(wǎng)(WirelessPAN),最初由愛立信創(chuàng)制,后來(lái)由藍(lán)牙技術(shù)聯(lián)盟訂定技術(shù)標(biāo)準(zhǔn)。據(jù)說(shuō)為了強(qiáng)調(diào)此技術(shù)及應(yīng)用尚在萌芽階段的意義,故將Bluetooth中文譯名為較文雅的“藍(lán)芽”,并在臺(tái)灣進(jìn)行商業(yè)的注冊(cè)。在2006年,藍(lán)牙技術(shù)聯(lián)盟組織已將全球中文譯名統(tǒng)一改采直譯為“藍(lán)牙”。藍(lán)牙的標(biāo)準(zhǔn)是IEEE802.15.1,藍(lán)牙協(xié)議工作在無(wú)需許可的ISM(IndustrialScientificMedical)頻段的2.45GHz。最高速度可達(dá)723.1kb/s。為了避免干擾可能使用2.45GHz的其它協(xié)議,藍(lán)牙協(xié)議將該頻段劃分成79頻道,(帶寬為1MHZ)每秒的頻道轉(zhuǎn)換可達(dá)1600次。拿藍(lán)牙與WiFi相比是不適當(dāng)?shù)?,因?yàn)閃iFi是一個(gè)更加快速的協(xié)議,覆蓋范圍更大。雖然兩者使用相同的頻率范圍,但是WiFi需要更加昂貴的硬件。藍(lán)牙設(shè)計(jì)被用來(lái)在不同的設(shè)備之間創(chuàng)建無(wú)線連接,而WiFi是個(gè)無(wú)線局域網(wǎng)協(xié)議。兩者的目的是不同的。第七章Android網(wǎng)絡(luò)通信Android藍(lán)牙通信—藍(lán)牙的基本知識(shí)開放式無(wú)線通訊標(biāo)準(zhǔn)設(shè)備短距離互聯(lián)解決方案定義:優(yōu)勢(shì):無(wú)需驅(qū)動(dòng)程序——獨(dú)特的配置文件小型化無(wú)線電低功率、低成本、安全性、穩(wěn)固易于使用、即時(shí)連接第七章Android網(wǎng)絡(luò)通信Android藍(lán)牙通信—藍(lán)牙的基本知識(shí)藍(lán)牙協(xié)議棧:核心協(xié)議層(基帶、主控制層接口HCI、鏈路管理協(xié)議LMP、邏輯鏈路控制和適配協(xié)議L2CAP、服務(wù)發(fā)現(xiàn)協(xié)議SDP)線纜替換協(xié)議層(無(wú)線射頻通信M)電話控制協(xié)議層(二進(jìn)制電話控制標(biāo)準(zhǔn)TCS-BIN、電話控制協(xié)議標(biāo)準(zhǔn)的AT命令集合)選用協(xié)議層(PPP、TCP、IP、UDP、OBEX、IrMC、WAP、WAE)具體介紹見備注第七章Android網(wǎng)絡(luò)通信Android藍(lán)牙通信—藍(lán)牙的基本知識(shí)藍(lán)牙協(xié)議棧圖解:vCard/vCalOBEXWAEWAPTCS-BINTCS-ATUDPTCP/IPPPPMSDPL2CAP語(yǔ)音LMP基帶藍(lán)牙無(wú)線電信道主控制器接口(HCI)第七章Android網(wǎng)絡(luò)通信Android藍(lán)牙通信—藍(lán)牙的基本知識(shí)藍(lán)牙立體聲音頻傳輸規(guī)范(A2DP)基本圖像規(guī)范(BIP)基本打印規(guī)范(BPP)無(wú)線電話規(guī)范(CTP)藍(lán)牙耳機(jī)規(guī)范(HP)文件傳輸規(guī)范(FTP)……藍(lán)牙規(guī)范(profile)——為了保證藍(lán)牙設(shè)備的互通性而制定的一系列規(guī)范藍(lán)牙應(yīng)用規(guī)范。藍(lán)牙應(yīng)用是根據(jù)藍(lán)牙SIG(特殊興趣小組)所稱的“應(yīng)用規(guī)范”進(jìn)行分類的,“profiles”就是形成使用模式的規(guī)程。藍(lán)牙應(yīng)用規(guī)范的目的是為應(yīng)用的互操作性提供構(gòu)架。藍(lán)牙應(yīng)用規(guī)范根據(jù)某個(gè)協(xié)議所能支持的特殊使用模式或功能來(lái)對(duì)這個(gè)協(xié)議的消息和特性進(jìn)行詳細(xì)說(shuō)明。使用模式包括傳送、局域網(wǎng)訪問(wèn)、目標(biāo)推進(jìn)和同步。一些藍(lán)牙應(yīng)用規(guī)范仍在定義之中,這兒列出由BluetoothSIG(specialinterestgroup)制定的一部分profile。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程Android平臺(tái)支持藍(lán)牙網(wǎng)絡(luò)協(xié)議棧,實(shí)現(xiàn)藍(lán)牙設(shè)備之間數(shù)據(jù)的無(wú)線傳輸。本小節(jié)描述了怎樣利用android平臺(tái)提供的藍(lán)牙API去實(shí)現(xiàn)藍(lán)牙設(shè)備之間的通信。

藍(lán)牙設(shè)備之間的通信主要包括了四個(gè)步驟:設(shè)置藍(lán)牙設(shè)備尋找局域網(wǎng)內(nèi)可能或者匹配的設(shè)備連接設(shè)備設(shè)備之間的數(shù)據(jù)傳輸Android所有關(guān)于藍(lán)牙開發(fā)的類都在android.bluetooth包下,一共有8個(gè)類,以下是建立藍(lán)牙連接的所需要的一些基本類:第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程--BluetoothAdapterBluetoothAdapter類:代表了一個(gè)本地的藍(lán)牙適配器,是所有藍(lán)牙交互的的入口點(diǎn)。利用它你可以發(fā)現(xiàn)其他藍(lán)牙設(shè)備,查詢綁定了的設(shè)備,使用已知的MAC地址實(shí)例化一個(gè)藍(lán)牙設(shè)備和建立一個(gè)BluetoothServerSocket(作為服務(wù)器端)來(lái)監(jiān)聽來(lái)自其他設(shè)備的連接。BluetoothAdapter里的方法很多,常用的有以下幾個(gè):

cancelDiscovery()

根據(jù)字面意思,是取消發(fā)現(xiàn),也就是說(shuō)當(dāng)我們正在搜索設(shè)備的時(shí)候調(diào)用這個(gè)方法將不再繼續(xù)搜索。

disable()關(guān)閉藍(lán)牙。

enable()打開藍(lán)牙

getAddress()獲取本地藍(lán)牙地址

getDefaultAdapter()獲取默認(rèn)BluetoothAdapter,實(shí)際上,也只有這一種方法獲取BluetoothAdapter

getName()獲取本地藍(lán)牙名稱

getRemoteDevice(Stringaddress)根據(jù)藍(lán)牙地址獲取遠(yuǎn)程藍(lán)牙設(shè)備

getState()獲取本地藍(lán)牙適配器當(dāng)前狀態(tài)(感覺可能調(diào)試的時(shí)候更需要)

isDiscovering()判斷當(dāng)前是否正在查找設(shè)備,是返回true

isEnabled()判斷藍(lán)牙是否打開,已打開返回true,否則,返回false第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程--

BluetoothDeviceBluetoothDevice類:代表了一個(gè)遠(yuǎn)端的藍(lán)牙設(shè)備,使用它請(qǐng)求遠(yuǎn)端藍(lán)牙設(shè)備連接或者獲取遠(yuǎn)端藍(lán)牙設(shè)備的名稱、地址、種類和綁定狀態(tài)。(其信息是封裝在bluetoothsocket中)。

獲取BluetoothDevice的目的——?jiǎng)?chuàng)建BluetoothSocket這個(gè)類:mSocketToServiceRecord(UUIDuuid)根據(jù)UUID創(chuàng)建并返回一個(gè)BluetoothSocket。其他方法,如getAddress(),getName(),同BluetoothAdapter。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程--

Bluetoothsocket

Bluetoothsocket類:代表了一個(gè)藍(lán)牙套接字的接口(類似于tcp中的套接字),是應(yīng)用程序通過(guò)輸入、輸出流與其他藍(lán)牙設(shè)備通信的連接點(diǎn)。一共5個(gè)方法,分別是

close(),與服務(wù)器斷開關(guān)閉

connect(),與服務(wù)器建立連接

getInptuStream(),獲取輸入流

getOutputStream(),獲取輸出流

getRemoteDevice(),獲取遠(yuǎn)程設(shè)備,指的是獲取bluetoothSocket指定連接的那個(gè)遠(yuǎn)程藍(lán)牙設(shè)備。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程--

Blueboothserversocket

Blueboothserversocket類:打開服務(wù)連接來(lái)監(jiān)聽可能到來(lái)的連接請(qǐng)求(屬于server端),為了連接兩個(gè)藍(lán)牙設(shè)備必須有一個(gè)設(shè)備作為服務(wù)器打開一個(gè)服務(wù)套接字。當(dāng)遠(yuǎn)端設(shè)備發(fā)起連接連接請(qǐng)求的時(shí)候,并且已經(jīng)連接到了的時(shí)候,Blueboothserversocket類將會(huì)返回一個(gè)bluetoothsocket。

只有三個(gè)方法:

兩個(gè)重載的accept(),accept(inttimeout)。兩者的區(qū)別在于后面的方法指定了過(guò)時(shí)時(shí)間,需要注意的是,執(zhí)行這兩個(gè)方法的時(shí)候,直到接收到了客戶端的請(qǐng)求(或是過(guò)期之后),都會(huì)阻塞線程,應(yīng)該放在新線程里運(yùn)行。這兩個(gè)方法都返回一個(gè)BluetoothSocket,最后的連接也是服務(wù)器端與客戶端的兩個(gè)BluetoothSocket的連接。close()關(guān)閉連接方法。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程在編程之前,需要在AndroidMainfest.xml中加入操作權(quán)限,代碼如下:<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/><uses-permissionandroid:name="android.permission.BLUETOOTH"/>1、獲取本地藍(lán)牙:必須確定你的設(shè)備支持藍(lán)牙,并保證他可以用。如果你的設(shè)備支持藍(lán)牙,將它使能。當(dāng)然,有兩種方法,一種是在你的系統(tǒng)設(shè)置里開啟藍(lán)牙,另外一中是在你的應(yīng)用程序里啟動(dòng)藍(lán)牙功能,第一種方法就不講了,具體講一個(gè)第二種方法:首先通過(guò)調(diào)用靜態(tài)方法getDefaultAdapter()獲取藍(lán)牙適配器bluetoothadapter,以后你就可以使用該對(duì)象了。如果返回為空,則說(shuō)明設(shè)備不支持藍(lán)牙功能。BluetoothAdaptermBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();if(mBluetoothAdapter==null){//DevicedoesnotsupportBluetooth}第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程其次,調(diào)用isEnabled()來(lái)查詢當(dāng)前藍(lán)牙設(shè)備的狀態(tài),如果返回為false,則表示藍(lán)牙設(shè)備沒有開啟,接下來(lái)你需要封裝一個(gè)ACTION_REQUEST_ENABLE請(qǐng)求到intent里面。例如:if(!mBluetoothAdapter.isEnabled()){IntentenableBtIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);}至此,如不出意外,恭喜你的藍(lán)牙設(shè)備已經(jīng)開啟了,接下來(lái)需要查找周邊可能存在的藍(lán)牙設(shè)備了。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程2、查找設(shè)備:使用bluetoothadapter類里的方法,你可以查找遠(yuǎn)端設(shè)備或者查詢?cè)谀闶謾C(jī)上已經(jīng)匹配(或者說(shuō)綁定)的其他手機(jī)了。當(dāng)然需要確定對(duì)方藍(lán)牙設(shè)備已經(jīng)開啟或者已經(jīng)開啟了“被發(fā)現(xiàn)使能“功能(對(duì)方設(shè)備是可以被發(fā)現(xiàn)的是你能夠發(fā)起連接的前提條件)。如果該設(shè)備是可以被發(fā)現(xiàn)的,會(huì)反饋回來(lái)一些對(duì)方的設(shè)備信息,比如名字、MAC地址等,利用這些信息,你的設(shè)備就可以選擇去向?qū)Ψ匠跏蓟粋€(gè)連接。如果你是第一次與該設(shè)備連接,那么一個(gè)配對(duì)的請(qǐng)求就會(huì)自動(dòng)的顯示給用戶。當(dāng)設(shè)備配對(duì)好之后,他的一些基本信息(主要是名字和MAC)被保存下來(lái)并可以使用藍(lán)牙的API來(lái)讀取。使用已知的MAC地址就可以對(duì)遠(yuǎn)端的藍(lán)牙設(shè)備發(fā)起連接請(qǐng)求。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程怎么查詢匹配好的設(shè)備:在建立連接之前你必須先查詢配對(duì)好了的藍(lán)牙設(shè)備集(你周圍的藍(lán)牙設(shè)備可能不止一個(gè)),以便你選取哪一個(gè)設(shè)備進(jìn)行通信,例如你可以查詢所有配對(duì)的藍(lán)牙設(shè)備,并使用一個(gè)數(shù)組適配器將其打印顯示出來(lái):Set<BluetoothDevice>pairedDevices=mBluetoothAdapter.getBondedDevices();//Iftherearepaireddevicesif(pairedDevices.size()>0){//Loopthroughpaireddevicesfor(BluetoothDevicedevice:pairedDevices){//AddthenameandaddresstoanarrayadaptertoshowinaListViewmArrayAdapter.add(device.getName()+"\n"+device.getAddress());}建立一個(gè)藍(lán)牙連接只需要MAC地址就已經(jīng)足夠了。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程3、掃描設(shè)備:掃描設(shè)備,只需要簡(jiǎn)單的調(diào)用startDiscovery()方法,這個(gè)掃描的過(guò)程大概持續(xù)是12秒,應(yīng)用程序?yàn)榱薃CTION_FOUND動(dòng)作需要注冊(cè)一個(gè)BroadcastReceiver來(lái)接受設(shè)備掃描到的信息。對(duì)于每一個(gè)設(shè)備,系統(tǒng)都會(huì)廣播ACTION_FOUND動(dòng)作。

掃描設(shè)備的樣例見備注。注意:掃描的過(guò)程是一個(gè)很耗費(fèi)資源的過(guò)程,一旦你找到你需要的設(shè)備之后,在發(fā)起連接請(qǐng)求之前,確保你的程序調(diào)用cancelDiscovery()方法停止掃描。顯然,如果你已經(jīng)連接上一個(gè)設(shè)備,啟動(dòng)掃描會(huì)減少你的通信帶寬。如果你想使你的設(shè)備能夠被其他設(shè)備發(fā)現(xiàn),將ACTION_REQUEST_DISCOVERABLE動(dòng)作封裝在intent中并調(diào)用startActivityForResult(Intent,int)方法就可以了。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙編程在你的應(yīng)用程序中,想建立兩個(gè)藍(lán)牙設(shè)備之間的連接,你必須實(shí)現(xiàn)客戶端和服務(wù)器端的代碼(因?yàn)槿魏我粋€(gè)設(shè)備都必須可以作為服務(wù)端或者客戶端)。一個(gè)開啟服務(wù)來(lái)監(jiān)聽,一個(gè)發(fā)起連接請(qǐng)求(使用服務(wù)器端設(shè)備的MAC地址)。當(dāng)他們都擁有一個(gè)藍(lán)牙套接字在同一M信道上的時(shí)候,可以認(rèn)為他們之間已經(jīng)連接上了。當(dāng)一個(gè)連接監(jiān)聽到的時(shí)候,服務(wù)端獲取到藍(lán)牙套接字。當(dāng)客戶可打開一個(gè)M信道給服務(wù)器端的時(shí)候,客戶端獲取到藍(lán)牙套接字。注意:在此過(guò)程中,如果兩個(gè)藍(lán)牙設(shè)備還沒有配對(duì)好的,android系統(tǒng)會(huì)通過(guò)一個(gè)通知或者對(duì)話框的形式來(lái)通知用戶。M連接請(qǐng)求會(huì)在用戶選擇之前阻塞。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙連接—服務(wù)端服務(wù)端的連接:

當(dāng)你想要連接兩臺(tái)設(shè)備時(shí),一個(gè)必須作為服務(wù)端(通過(guò)持有一個(gè)打開的bluetoothserversocket),目的是監(jiān)聽外來(lái)連接請(qǐng)求,當(dāng)監(jiān)聽到以后提供一個(gè)連接上的bluetoothsocket給客戶端,當(dāng)客戶端從bluetoothserversocket得到bluetoothsocket以后就可以銷毀bluetoothserversocket,除非你還想監(jiān)聽更多的連接請(qǐng)求。建立服務(wù)套接字和監(jiān)聽連接的基本步驟如下:1、首先通過(guò)調(diào)用mWithServiceRecord(String,UUID)方法來(lái)獲取bluetoothserversocket對(duì)象。2、其次調(diào)用accept()方法來(lái)監(jiān)聽可能到來(lái)的連接請(qǐng)求,當(dāng)監(jiān)聽到以后,返回一個(gè)連接上的藍(lán)牙套接字bluetoothsocket。3、最后,在監(jiān)聽到一個(gè)連接以后,需要調(diào)用close()方法來(lái)關(guān)閉監(jiān)聽程序。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙連接—服務(wù)端注意:accept()方法不應(yīng)該放在主Acitvity里面,因?yàn)樗且环N阻塞調(diào)用(在沒有監(jiān)聽到連接請(qǐng)求之間程序就一直停在那里)。解決方法是新建一個(gè)線程來(lái)管理。示例代碼見備注。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙連接—客戶端客戶端連接為了初始化一個(gè)與遠(yuǎn)端設(shè)備的連接,需要先獲取代表該設(shè)備的一個(gè)bluetoothdevice對(duì)象。通過(guò)bluetoothdevice對(duì)象來(lái)獲取bluetoothsocket并初始化連接:使用bluetoothdevice里的方法mSocketToServiceRecord(UUID)來(lái)獲取bluetoothsocket。UUID就是匹配碼。調(diào)用connect()方法。如果遠(yuǎn)端設(shè)備接收了該連接,他們將在通信過(guò)程中共享M信道,并且connect()方法返回。示例代碼見備注。注意:conncet()方法也是阻塞調(diào)用,一般建立一個(gè)獨(dú)立的線程中來(lái)調(diào)用該方法。在設(shè)備discover過(guò)程中不應(yīng)該發(fā)起連接connect(),這樣會(huì)明顯減慢速度以至于連接失敗。且數(shù)據(jù)傳輸完成只有調(diào)用close()方法來(lái)關(guān)閉連接,這樣可以節(jié)省系統(tǒng)內(nèi)部資源。第七章Android網(wǎng)絡(luò)通信Android平臺(tái)的藍(lán)牙連接—客戶端管理連接(主要涉及數(shù)據(jù)的傳輸):當(dāng)設(shè)備連接上以后,每個(gè)設(shè)備都擁有各自的bluetoothsocket。現(xiàn)在你就可以實(shí)現(xiàn)設(shè)備之間數(shù)據(jù)的共享了。1.首先通過(guò)調(diào)用getInputStream()和getOutputStream()方法來(lái)獲取輸入輸出流。然后通過(guò)調(diào)用read(byte[])和write(byte[]).方法來(lái)讀取或者寫數(shù)據(jù)。2.實(shí)現(xiàn)細(xì)節(jié):以為讀取和寫操作都是阻塞調(diào)用,需要建立一個(gè)專用線程來(lái)管理。線程示例見備注:第七章Android網(wǎng)絡(luò)通信AndroidWIFI—WIFI簡(jiǎn)介Wi-Fi原先是無(wú)線保真的縮寫,Wi-Fi的英文全稱為wirelessfidelity,在無(wú)線局域網(wǎng)的范疇是指“無(wú)線相容性認(rèn)證”,實(shí)質(zhì)上是一種商業(yè)認(rèn)證,同時(shí)也是一種無(wú)線聯(lián)網(wǎng)的技術(shù),以前通過(guò)網(wǎng)線連接電腦,而現(xiàn)在則是通過(guò)無(wú)線電波來(lái)連網(wǎng);常見的就是一個(gè)無(wú)線路由器,那么在這個(gè)無(wú)線路由器的電波覆蓋的有效范圍都可以采用WIFI連接方式進(jìn)行聯(lián)網(wǎng),如果無(wú)線路由器連接了一條ADSL線路或者別的上網(wǎng)線路,則又被稱為“熱點(diǎn)”。Wi-Fi是一種幫助用戶訪問(wèn)電子郵件、Web和流式媒體的互聯(lián)網(wǎng)技術(shù)。它為用戶提供了無(wú)線的寬帶互聯(lián)網(wǎng)訪問(wèn)。同時(shí),它也是在家里、辦公室或在旅途中上網(wǎng)的快速、便捷的途徑。能夠訪問(wèn)Wi-Fi網(wǎng)絡(luò)的地方被稱為熱點(diǎn)。Wi-Fi或802.11G在2.4Ghz頻段工作,所支持的速度最高達(dá)54Mbps。另外還有兩種802.11空間的協(xié)議,包括(a)和(b)。它們也是公開使用的,但802.11G在世界上最為常用。第七章Android網(wǎng)絡(luò)通信WIFI模塊第七章Android網(wǎng)絡(luò)通信WIFI網(wǎng)卡的狀態(tài)WIFI網(wǎng)卡的狀態(tài)是由一系列的整形常量來(lái)表示的:0-->WIFI_STATE_DISABLING1-->WIFI_STATE_DISABLED2-->WIFI_STATE_ENABLING3-->WIFI_STATE_ENABLED4-->WIFI_STATE_UNKNOWN其中0表示網(wǎng)卡正在關(guān)閉;1表示網(wǎng)卡不可用,2表示網(wǎng)卡正在打開,3表示網(wǎng)卡可用,4表示未知網(wǎng)卡狀態(tài)。第七章Android網(wǎng)絡(luò)通信AndroidMenifest.xml中WIFI權(quán)限設(shè)置<!--

以下是使用wifi訪問(wèn)網(wǎng)絡(luò)所需要的權(quán)限--><u

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論