Android 藍牙開發(整理大全)

 Android藍牙開發


鑑於國內Android藍牙開發的例子不多,以及藍牙開發也比較少用到,因此找的資料不是很全

(一):


因爲Android藍牙的通訊都須要用到UUID,若是由手機發起搜索,當搜索到電腦的藍牙時,可以獲得藍牙的地址(address),但通訊時須要獲得BluetoothSocket,而BluetoothSocket則須要電腦藍牙的UUID,請問這個是怎麼樣獲得的呢?html

在藍牙中,每一個服務和服務屬性都惟一地由"全球惟一標識符" (UUID)來校驗。正如它的名字所暗示的,每個這樣的標識符都要在時空上保證惟一。UUID類可表現爲短整形(16或32位)和長整形(128 位)UUID。他提供了分別利用String和16位或32位數值來建立類的構造函數,提供了一個能夠比較兩個UUID(若是兩個都是128位)的方法,還有一個能夠轉換一個UUID爲一個字符串的方法。UUID實例是不可改變的(immutable),只有被UUID標示的服務能夠被發現。
    在Linux下你用一個命令uuidgen -t能夠生成一個UUID值;在Windows下則執行命令uuidgen 。UUID看起來就像以下的這個形式:2d266186-01fb-47c2-8d9f-10b8ec891363。當使用生成的UUID去建立一個 UUID對象,你能夠去掉連字符。java

我搞定了電腦和android手機的藍牙通訊問題:
首先解答幾個問題
1.兩邊的UUID必須是同樣的,這是一個服務的惟一標識,並且這個UUID的值必須是
00001101-0000-1000-8000-00805F9B34FB。爲何呢?由於這個是android的API上面說明的,用於普通藍牙適配器和android手機藍牙模塊鏈接的,請你們本身看一下android有關bluetooth的API。
2.在鏈接的時候,若是電腦做爲server(一直監聽是否有服務鏈接),android手機做爲client(主動和電腦創建鏈接),則須要在手機端調用這樣一行代碼:mmSocket.connect();
其中mmSocket是一個BluetoothSocket類,在這句話以前請肯定你已經把手機和電腦進行了配對,並且那些亂七八糟的設置都搞定了。linux

http://developer.android.com/reference/android/bluetooth/BluetoothDevice.htmlandroid

public BluetoothSocket createInsecureRfcommSocketToServiceRecord (UUID uuid)
Since: API Level 10Create an RFCOMM BluetoothSocket socket ready to start an insecure outgoing connection to this remote device using SDP lookup of uuid.程序員

The communication channel will not have an authenticated link key i.e it will be subject to man-in-the-middle attacks. For Bluetooth 2.1 devices, the link key will be encrypted, as encryption is mandatory. For legacy devices (pre Bluetooth 2.1 devices) the link key will be not be encrypted. UsecreateRfcommSocketToServiceRecord(UUID) if an encrypted and authenticated communication channel is desired.api

This is designed to be used with listenUsingInsecureRfcommWithServiceRecord(String, UUID) for peer-peer Bluetooth applications.服務器

Use connect() to initiate the outgoing connection. This will also perform an SDP lookup of the given uuid to determine which channel to connect to.app

The remote device will be authenticated and communication on this socket will be encrypted.框架

Hint: If you are connecting to a Bluetooth serial board then try using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB. However if you are connecting to an Android peer then please generate your own unique UUID.socket



(二):

         Android對於藍牙開發從2.0版本的sdk纔開始支持,並且模擬器不支持,測試至少須要兩部手機,因此制約了不少技術人員的開發。

        首先,要操做藍牙,先要在AndroidManifest.xml里加入權限

<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" />

<uses-permissionandroid:name="android.permission.BLUETOOTH" />


         而後,看下api,Android全部關於藍牙開發的類都在android.bluetooth包下,以下圖,只有8個類

 

而咱們須要用到了就只有幾個而已:

    1.BluetoothAdapter 顧名思義,藍牙適配器,直到咱們創建bluetoothSocket鏈接以前,都要不斷操做它

      BluetoothAdapter裏的方法不少,經常使用的有如下幾個:

      cancelDiscovery() 根據字面意思,是取消發現,也就是說當咱們正在搜索設備的時候調用這個方法將再也不繼續搜索

      disable()關閉藍牙

      enable()打開藍牙,這個方法打開藍牙不會彈出提示,更多的時候咱們須要問下用戶是否打開,一下這兩行代碼一樣是打開藍牙,不過會提示用戶:

Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enabler,reCode);//同startActivity(enabler);

      getAddress()獲取本地藍牙地址

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

      getName()獲取本地藍牙名稱

      getRemoteDevice(String address)根據藍牙地址獲取遠程藍牙設備

      getState()獲取本地藍牙適配器當前狀態(感受可能調試的時候更須要)

      isDiscovering()判斷當前是否正在查找設備,是返回true

      isEnabled()判斷藍牙是否打開,已打開返回true,不然,返回false

     listenUsingRfcommWithServiceRecord(String name,UUID uuid)根據名稱,UUID建立並返回BluetoothServerSocket,這是建立BluetoothSocket服務器端的第一步

      startDiscovery()開始搜索,這是搜索的第一步

    2.BluetoothDevice看名字就知道,這個類描述了一個藍牙設備

       createRfcommSocketToServiceRecord(UUIDuuid)根據UUID建立並返回一個BluetoothSocket


       這個方法也是咱們獲取BluetoothDevice的目的——建立BluetoothSocket


       這個類其餘的方法,如getAddress(),getName(),同BluetoothAdapter

    3.BluetoothServerSocket若是去除了Bluetooth相信你們必定再熟悉不過了,既然是Socket,方法就應該都差很少,


這個類一種只有三個方法


兩個重載的accept(),accept(inttimeout)二者的區別在於後面的方法指定了過期時間,須要注意的是,執行這兩個方法的時候,直到接收到了客戶端的請求(或是過時以後),都會阻塞線程,應該放在新線程裏運行!


還有一點須要注意的是,這兩個方法都返回一個BluetoothSocket,最後的鏈接也是服務器端與客戶端的兩個BluetoothSocket的鏈接

      close()這個就不用說了吧,翻譯一下——關閉!

    4.BluetoothSocket,跟BluetoothServerSocket相對,是客戶端


一共5個方法,不出意外,都會用到

      close(),關閉

      connect()鏈接

      getInptuStream()獲取輸入流

      getOutputStream()獲取輸出流

      getRemoteDevice()獲取遠程設備,這裏指的是獲取bluetoothSocket指定鏈接的那個遠程藍牙設備


(三):

1. 概述

  Bluetooth 是幾乎如今每部手機標準配備的功能,多用於耳機 mic 等設備與手機的鏈接,除此以外,還能夠多部手機之間創建 bluetooth 通訊,本文就經過 SDK 中帶的一個聊天室的例程,來介紹一下 Android 上的 Bluetooth 的開發。

  在 Android1.x 的時候,相關 API 很是不完善,還不能簡單的使用 Bluetooth 開發,有一個開源項目能夠幫助程序員使用、開發藍牙,支持直接方法bluetooth 協議棧。在 Android2 之後,框架提供了一些官方 API 來進行藍牙的通訊,但目前的程序也比較不完善。本文主要討論 Android2 後的Bluetooth 通訊的 API 使用方法。

  首先看聊天室的效果圖:

  

1.gif

 

  2. Bluetooth 通訊 API 介紹2.1. Bluetooth 通訊過程

  

2.gif

 2.2. Bluetooth API 的主要方法

 

  BluetoothAdapter 類

  BluetoothAdapter.getDefaultAdapter() :獲得本地默認的 BluetoothAdapter ,若返回爲 null 則表示本地不支持藍牙;

  isDiscovering() :返回設備是否正在發現周圍藍牙設備;

  cancelDiscovery() :取消正在發現遠程藍牙設備的過程;

  startDiscovery() :開始發現過程;

  getScanMode() :獲得本地藍牙設備的 Scan Mode ;

  getBondedDevices() :獲得已配對的設備;

  isEnabled() :藍牙功能是否啓用。

  當發現藍牙功能未啓用時,以下調用設置啓用藍牙:

  if (! mBluetoothAdapter .isEnabled()) {

  Intent enableIntent = new Intent(BluetoothAdapter. ACTION_REQUEST_ENABLE );

  startActivityForResult(enableIntent, REQUEST_ENABLE_BT );

  }

  複製代碼

  若是發現當前設備沒有打開對外可見模式,則傳遞 Intent 來調用打開可發現模式,代碼以下:

  Intent discoverableIntent = new Intent(BluetoothAdapter. ACTION_REQUEST_DISCOVERABLE ); discoverableIntent.putExtra(BluetoothAdapter. EXTRA_DISCOVERABLE_DURATION , 300);

  startActivity(discoverableIntent);

  複製代碼

  BluetoothDevice 類,此爲對應的遠程藍牙 Device

  createRfcommSocketToServiceRecord() :建立該 Device 的 socket 。

  BluetoothSocket 類

  connect() :請求鏈接藍牙。

  getInputStream() :獲得輸入流,用於接收遠程方信息。

  getOutputStream() :獲得輸出流,發送給遠程方的信息。

  close() :關閉藍牙鏈接。

  InputStream 類:

  read(byte[]) :以阻塞方式讀取輸入流。

  OutputStream 類:

  write(byte[]) :將信息寫入該輸出流,發送給遠程。


..

3. BluetoothChat 例程分析

  Google 提供的關於 Bluetooth 開發的例程爲 Bluetoothchat ,使用截圖可見本文一開始。除去配置及 ui 定義等文件,主程序文件共三個:BluetoothChat.java 、 BluetoothChatService.java 以及 DeviceListActivity.java ,詳細功能可見下面的描述。

  3.1. 總體調用關係序列圖

  

3.gif

 3.2. BluetoothChat.java

 

  例程的主 Activity 。 onCreate() 獲得本地 BluetoothAdapter 設備,檢查是否支持。 onStart() 中檢查是否啓用藍牙,並請求啓用,而後執行 setupChat()。 setupChat() 中先對界面中的控件進行初始化增長點擊監聽器等,然建立 BluetoothChatService 對象,該對象在整個應用過程當中存在,並執行藍牙鏈接創建、消息發送接受等實際的行爲。

  3.3. BluetoothChatService.java

  public synchronized void start() :

  開啓 mAcceptThread 線程,因爲樣例程序是僅 2 人的聊天過程,故以前先檢測 mConnectThread 和 mConnectedThread 是否運行,運行則先退出這些線程。

  public synchronized void connect(BluetoothDevice device) :

  取消 CONNECTING 和 CONNECTED 狀態下的相關線程,而後運行新的 mConnectThread 線程。

  public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) :

  開啓一個 ConnectedThread 來管理對應的當前鏈接。以前先取消任意現存的 mConnectThread 、 mConnectedThread 、 mAcceptThread 線程,而後開啓新 mConnectedThread ,傳入當前剛剛接受的 socket 鏈接。最後經過 Handler 來通知 UI 鏈接 OK 。

  public synchronized void stop() :

  中止全部相關線程,設當前狀態爲 NONE 。

  public void write(byte[] out) :

  在 STATE_CONNECTED 狀態下,調用 mConnectedThread 裏的 write 方法,寫入 byte 。

  private void connectionFailed() :

  鏈接失敗的時候處理,通知 ui ,並設爲 STATE_LISTEN 狀態。

  private void connectionLost() :

  當鏈接失去的時候,設爲 STATE_LISTEN 狀態並通知 ui 。

  內部類:

  private class AcceptThread extends Thread :

  建立監聽線程,準備接受新鏈接。使用阻塞方式,調用 BluetoothServerSocket.accept() 。提供 cancel 方法關閉 socket 。

  private class ConnectThread extends Thread :

  這是定義的鏈接線程,專門用來對外發出鏈接對方藍牙的請求和處理流程。構造函數裏經過 BluetoothDevice.createRfcommSocketToServiceRecord(),從待鏈接的 device 產生 BluetoothSocket. 而後在 run 方法中 connect ,成功後調用 BluetoothChatSevice 的 connected() 方法。定義 cancel() 在關閉線程時可以關閉相關 socket 。

  private class ConnectedThread extends Thread :

  這個是雙方藍牙鏈接後一直運行的線程。構造函數中設置輸入輸出流。 Run 方法中使用阻塞模式的 InputStream.read() 循環讀取輸入流, 而後 post 到UI 線程中更新聊天消息。也提供了 write() 將聊天消息寫入輸出流傳輸至對方,傳輸成功後回寫入 UI 線程。最後 cancel() 關閉鏈接的 socket 。

  3.4. DeviceListActivity.java

  該類包含 UI 和操做的 Activity 類,做用是獲得系統默認藍牙設備的已配對設備列表,以及搜索出的未配對的新設備的列表。而後提供點擊後發出鏈接設備請求的功能。

  除了 RFCOMM 通訊外, Android 上關於 Bluetooth 的還有 SDP 、 GAP 、耳機設備鏈接等內容,本文還未涉及,將會隨着藍牙相關 API 在新版本中的進一步完善來學習使用。




以上資料包含三大部分,有時間會把代碼搞上去供你們參考.

~.~
相關文章
相關標籤/搜索