Android藍芽CS通訊機制的深入挖掘與使用

來源:互聯網
上載者:User

Android藍芽CS通訊機制的深入挖掘與使用

個人說明:以下所用到的資料均來源於網路,筆者會在重要部分標明出處。本文不涉及任何公司的機密檔案。鑒於個人水平有限,如果讀者發現有任何錯誤之處,希望讀者能與本人聯絡。因為我個人CSDN的部落格不知道為什麼上不去了,為了美觀,代碼選擇了貼圖。如果需要文中任何代碼可以聯絡我chlianghui@gmail.com.

前言

藍芽是目前為止手機近距離通訊的主要方法,Android的藍芽功能的成長我們也有目共睹。接下來我將通過一個小小的基於Client Server的資料通訊的例子講解藍芽傳輸的方方面面,包括Android藍芽基本知識、藍芽服務、自訂服務的使用這三個大方面。

一、Android藍芽基本知識。

關於藍芽操作的基本知識網路上和書很多地方都有講解,本文主要參考了網上比較經典的http://www.eoeandroid.com/thread-18993-1-1.html這篇文章,大家可以先看看,我們這裡以補充為主。而和藍芽有關的類原始碼可到http://www.google.com/codesearch上面搜尋有關原始碼。

1.Android中使用藍芽開發前要加上許可權:android.permission.BLUETOOTH和android.permission.BLUETOOTH_ADMIN

2.對於操作手機藍芽功能的部分,如開啟藍芽、可見、搜尋、配對串連,等,我們主要用到BluetoothAdapter和BluetoothDevice這兩個類。

Adapter代表的是本機上的藍芽模組,故此類一般是跟本機有關的內容。

而Device代表得則是藍芽搜尋到的一個遠端裝置,故此類一般是與針對遠端裝置進行操作有關的內容。

3.對於藍芽的資料操作功能的部分,我們需要用到BluetoothSocket和BluetoothServerSocket這兩個類。

接下來我們在我們的樣本程式中應用以上的類讓兩部手機完成一次配對串連。假設我們有兩部手機,一部為Client,一部為Server。開啟藍芽的代碼省略。

Server主要程式碼片段如下:

圖1.1 Server註冊服務的主要代碼

Client主要程式碼片段如下:

圖1.2 Client串連服務的主要代碼

二、藍芽服務

首先介紹一下UUID,在藍芽中,每個服務和服務屬性都唯一地由"全球唯一識別碼" (UUID)來校正。正如它的名字所暗示的,每一個這樣的標識符都要在時空上保證唯一。UUID類可表現為短整形(16或32位)和長整形(128 位)UUID。他提供了分別利用String和16位或32位元值來建立類的建構函式,提供了一個可以比較兩個UUID(如果兩個都是128位)的方法,還有一個可以轉換一個UUID為一個字串的方法。(原創未找到,引用自http://www.bitscn.com/pdb/java/200605/22644.html )

眾所周知,在我們的TCP/IP協議下,每個連接埠都可以對應一種服務,例如HTTP協議對應80這個連接埠。而在Bluetooth協議下,同樣的,一個藍芽模組服務也對應著一個連接埠。在藍牙裝置用BluetoothAdapter的listenUsingRfcommWithServiceRecord的方法註冊一個服務的時候,系統就會為之指派一個連接埠。我們可以通過查看BluetoothAdapter的原始碼研究其原理:

圖2.1 listenUsingRFcommWithServiceRecord程式碼片段1

可以看到該函數先用傳入的UUID作為參數建立了一個叫RfcommChannelPicker的類,我們不妨顧名思義,先入為主,認為它就是針對UUID分配尋找channel的一個類。追根溯源,看看它裡面有些什麼:

 圖2.2 RfcommChannelPicker的類成員

首先我們看看類成員,映入眼帘的是4個排列得很整齊的數字組成的數組reserved,而且後面還有注釋,咱們Google百度搜搜搜狗或有道一下,HFAG(handsfree audio gateway)可能是跟藍芽免提服務有關,HSAG(headset audio gateway)可能跟藍芽耳機服務有關,而OPUSH(Object Push)就是OPP服務,通過這個服務我們可以推送對象到另一部有這個服務的手機,而PBAP(PhoneBook Access)則是提供通過藍芽傳送手機電話本的一個服務合約。而它們都對應著數字,是否意味著這些藍芽服務對應的channel已經是被系統保留了呢?(就像http是80一樣),我們需要進一步確認。

 圖2.3 RfcommChannelPicker的建構函式和nextChannel函數

首先我們可以看到程式將一串聯續的數字加入到sChannel這個list中,通過查看,我們得到MAX_RFCOMM_CHANNEL數值為30,而後,又把sChannel中,與reserved數組中相等的元素remove了。然後將可用的channel數字複製到mChannels中,在nextChannel函數中,我們可以知道程式通過random的方法來給uuid配對channel。

最後我們發現在listenUsingRFcommWithServiceRecord中有這樣的一段代碼:

 圖2.4 listenUsingRFcommWithServiceRecord代碼

而BluetoothServerSocket的原型是:

 圖 2.5 BluetoothServerSocket的原型

至此可知,當我們使用BluetoothAdapter的listenUsingRFcommWithServiceRecord建立一個服務的時候,系統會為其分配一個channel(其實就是port),然後調用native的函數,建立一個socket。我們如果用C對Android進行開發的話,要建立服務就要注意使用port。

那麼,我們現在知道UUID其實也是對應著port的服務而已,那麼當我們搜尋到Device之後,怎麼知道Device上究竟提供了什麼服務?

我們翻查BluetoothDevice,發現有一個這樣的函數:

 圖2.6 getuuid函數

這個看起來好像是我們需要的函數,雖然它被hide了,但是我們嘗試著用反射機制調用之。代碼如下:

 圖2.7 獲得遠端藍牙裝置提供服務的方法

其中device是我們要尋找服務的裝置。我用這段代碼查查咱們的“國產神機”M某吧。

結果在logcat中顯示:

圖2.8 M9提供的藍芽服務

Run了上面一段程式後得到這個UUID list,其中0000112f-0000-1000-8000-00805f9b34fb就是剛才我們提到過的PBAP服務的UUID。如果用這段代碼搜沒配過對的手機,得到的結果為空白,因為這個getUuids的真身其實是BluetoothService類裡面的getUuidFromCache(對getUuids進行追根溯源),是在本機與遠端機配對串連的過程中儲存下來的。

現在我們用以下代碼在M9上面註冊一個服務:

 圖2.9 為M9註冊藍芽服務

其中所用到的UUID是用UUIDMaker產生的。(第三部分會講)然後測試圖2.6程式碼片段的手機與M9先將配對狀態取消掉,重新配對一次,再運行圖2.6的程式碼片段,我們可以看到以下的結果:

 圖2.10  M9提供的藍芽服務2

可以看到我們註冊的服務已經能成功被搜尋到了!這就是為什麼我們調用BluetoothDevice的createRfcommSocketToServiceRecord函數能串連上對方提供的服務的原因。而createRfcommSocketToServiceRecord裡面又是怎樣的原理,可以用同樣的方法去深挖。

三、自訂服務藍芽傳輸的實現

既然我們弄懂了這個藍芽服務其實是怎麼回事,那麼我們就可以自己建立自己的服務了哦!好,先別激動,一種服務應該對應一種協議,就像去飲料店,你需要飲料,然後給錢,然後店員給飲料,這就是飲料服務的一種無形的協議。

1.自訂協議

首先確定我們要做什麼,相信做藍芽開發的人一定看過BluetoothChat這個經典的例子,它功能只限於傳輸文字,那麼我們要改進它,要加入在聊天的過程中傳輸檔案的功能應怎麼做?我們定義這樣的一種協議(假設雙方都已經建立好串連):

a.發送資訊方先發一個標誌,說明我接下來要發的是普通的聊天字元還是檔案,例如0xEE代表“我要說話”,0xEF代表“我要發檔案”。

b.然後發送方再發接下來內容的長度,假設要發字元(這時候程式已經在UI層擷取了發送人說的話)長度為10個位元組,就發0x0A,假設要發的檔案是11個位元組大小,就發0x0B。然後發送人就根據需要發送內容。

c.接收方收到首個位元組,知道接下來是什麼內容。然後再收第二個位元組知道內容的長度。然後接收這個長度的內容。根據內容的類型(首位元組),決定是顯示在聊天介面還是儲存到儲存介質上。

以上簡單的幾步就是一個自訂的服務合約。

2.建立屬於自己的UUID

為了不讓自己創造的服務不與其他人的衝突,所以一定要註冊一個全球唯一的uuid,這裡有一款工具UUIDMaker,上網搜就搜到,而且使用非常簡單。介面如下:

 圖3.1UUIDMAker介面

在協議和UUID都完成後,編寫代碼就事半功倍了。

Server端的核心代碼:

 圖3.2 Server核心原始碼

Client端的核心代碼:

 圖3.3 Client核心原始碼

另外需要說明的是,在第二部分中我們看到M9還有很多系統提供的服務,例如PBAP、OPP等,我們一樣可以用以上用戶端的方法來使用這些服務,但是首先我們需要清楚這些服務的工作原理,就要首先閱讀相關的資料和查看原始碼。

四、總結

本文主要針對藍芽服務註冊原理、使用方法進行了比較深入的講解,讓開發人員對藍芽CS方式下的通訊操作更加瞭解。筆者認為,研究Android的原始碼是Android開發人員提升自己開發水平最好的方法,而閱讀加測試的方法則令研究的效果事半功倍。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.