Android藍牙通信-2016-05-30

近來工作做了很多Android手機對接藍牙設備的工作,記錄一下。

場景

需要對接藍牙設備,發送或者獲取數據,比如藍牙打印機、藍牙體脂稱、藍牙電子血壓計、藍牙血糖儀、藍牙身高尺等等。大致的過程就是手機跟設備互相連接認證,互傳數據的過程。當然,對接不同的設備,會有不同的交互流程,同一類設備,針對不同廠商,也需要遵循不同廠商定制的SDK的相關協議。但都離不開藍牙的核心協議,下面分經典藍牙2.0以及低功耗藍牙4.0(BLE)。

經典藍牙2.0

比較傳統的設備只支持藍牙2.0,SPP協議、HDP協議
過程:掃描,配對,連接,通信

參考:Android 藍牙開發基本流程

1、通用UUID:
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
2、配對,反射設置密碼(如果需要設置的話)
Method removeBondMethod = btClass.getDeclaredMethod("setPin",  new Class[] { byte[].class }); 
return value = (Boolean) removeBondMethod.invoke(bluetoothDevice,  new Object[] { password.getBytes() });
3、配對,反射調用綁定方法
Method createBondMethod = btClass.getMethod("createBond");
Boolean value = (Bovolean) createBondMethod.invoke(btDevice);
4、連接,根據不同SDK方式

問題:getBluetoothService() called with no BluetoothManagerCallback

int sdk = Build.VERSION.SDK_INT;
if (sdk >= 10) {
    socket = mDevice.createInsecureRfcommSocketToServiceRecord(SPP_UUID);
} else {
    socket = mDevice.createRfcommSocketToServiceRecord(SPP_UUID);
}

低功耗藍牙4.0技術(BLE)

注意:從Android4.3(API-18)開始支持BLE,但只支持作為中心設備模式Central,也就是只支持Android設備主動掃描連接外圍設備Peripheral,在Android5.0(API-21)兩種模式都支持。藍牙4.0將三種規格集一體,包括傳統藍牙技術、高速技術和低耗能技術
參考:最全最詳細的藍牙版本介紹包含藍牙4.0和4.1
過程:掃描,連接,發現服務,通信

1、獲取BluetoothAdapter
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
2、判斷是否支持藍牙,并打開藍牙(利用系統Intent的方式請求打開藍牙)
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
3、搜索BLE設備
mBluetoothAdapter.startLeScan(mLeScanCallback);
BluetoothAdapter.LeScanCallback // 搜索回調

注意:搜索時,你只能搜索傳統藍牙設備或者BLE設備,兩者完全獨立,不可同時被搜索。
實際使用:使用經典藍牙搜索方式startDiscovery()能同時搜索到百捷2.0和百捷4.0的設備

4、連接GATT Server
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
BluetoothGattCallback // 連接回調
5、連接成功。BluetoothGatt常規用到的幾個操作示例
connect(); // 連接遠程設備。
discoverServices(); // 搜索連接設備所支持的service。
disconnect(); // 斷開與遠程設備的GATT連接。
close(); // 關閉GATT Client端。
readCharacteristic(characteristic); // 讀取指定的characteristic。
setCharacteristicNotification(characteristic, enabled); // 設置當指定characteristic值變化時,發出通知。
getServices(); // 獲取遠程設備所支持的services。

一些實踐心得

關于藍牙硬件

對接藍牙設備,一方面由于藍牙設備的多樣性,另一方面Android手機硬件、系統的多樣性,會遇到比較多的問題就是藍牙連接的穩定性問題。關于這個問題也是嘗試了很多種方法去避免,分析其中一個原因就是:由代碼驅動藍牙硬件的過程,需要一定的時間,一定的時間等待,會帶來極大穩定性的提高。比如啟動藍牙后延遲300ms在執行其他操作。另一個就是可以采用線程輪詢判斷一個狀態是否已經啟動,比如循環5次,每隔1秒執行判斷操作。

關于優化

必要時,考慮采用服務Service去獲取設備的數據,或者設置單例模式。

如有錯誤,歡迎拍磚!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,446評論 25 708
  • Guide to BluetoothSecurity原文 本出版物可免費從以下網址獲得:https://doi.o...
    公子小水閱讀 8,315評論 0 6
  • 公司的項目最近需要用到藍牙開發的相關內容,因此特地查閱了Google官方文檔的內容并進行二次整理,希望能對需要學習...
    Chuckiefan閱讀 32,577評論 44 123
  • 前言: 本文主要描述Android BLE的一些基礎知識及相關操作流程,不牽扯具體的業務實現,其中提供了針對廣播包...
    幻影宇寰閱讀 5,419評論 6 19
  • 1.時間不受控。 48個人的時間、空間同時對上,可能性為零。即使三分之一的人相聚也變得難上加難。 這是二十年后漸漸...
    高小花0218閱讀 268評論 0 0