Android BLE 蓝牙开发-扫码枪集成
一、藍牙模式HID與BLE
當掃碼槍與手機連接時,通常采用的是藍牙HID(Human Interface Device)模式。本質上是一個把掃碼槍作為一個硬件鍵盤,按照鍵盤協議把掃碼后的結果逐個輸入到對應的控件上。
優點:無需開發集成,配對就可以立即作為鍵盤輸入使用??梢允褂幂斎肟虻冉M件直接接收掃碼結果。
缺點:對非數字支持不佳,與輸入法相關,在某些時候會觸發英文聯想-_-||,與虛擬鍵盤會發生沖突,連接掃碼槍時需要切換鍵盤輸入法輸入。
而我們要掃描的標簽,不僅有英文,特殊符號,還有中文,因此以HID模式接入的藍牙掃碼槍,最終是不能滿足要求的。于是重新選型了支持BLE模式的掃碼槍。
BLE模式掃碼槍
優點:兼容性好,遵循藍牙協議,與鍵盤輸入法無關。更底層,直接返回原始二進制數據流,方便判定編碼以及進行字符編碼轉換。
缺點:需要進行原生開發, 處理設備掃描,連接,數據讀寫等操作。
二、BLE協議白話
好在有github,其中的?BLESSED for Android - BLE made easy 項目,就是一個致力于簡化android上BLE開發工作的開源庫。但在擼代碼前還是要簡單理解下BLE協議的主要概念。
較為重要的兩個東西是Service(服務)?與Characteristic(特性,譯為功能可能更好理解),簡而言之,一個設備可以提供多個服務,每個服務可以提供多個特性功能,每個服務及特性對應一個UUID。
與設備的通信通過功能進行,每個功能通過Properties(屬性)表明該特性支持讀,寫或者通知。
為了便于理解BLE協議,推薦下載一個叫做“BLE調試助手”的APP。下面是APP的截圖。
????
? ?
????????截圖演示了如何從一個支持BLE協議的設備中讀取電量,不需要提前配對,打開APP掃描到對應設備后,點擊Connect, 隨后列出的就是一堆上面說的Service(服務),能夠顯示服務名稱的如“Battery Service”,是根據UUID的約定取得的。
如電池服務為0x180F。點開服務后是Characteristic,其中的Battery Level(也是UUID約定 0x2A19)的Properties為 READ NOTIFY,表明該特性支持讀取和通知。
點擊那個下箭頭,點擊讀取,顯示出返回數據為0x5D(十進制估計九十多:-0)。
電池服務是一個在協議中約定的標準服務,但掃碼槍的似乎不是,我們還需要找到掃碼后,是通過哪個Service的哪個Characteristic進行通知的,通過這個工具APP也不難找,注意,要打開那個接受通知數據。
掃碼后會有數據顯示,找到之后就可以開始編碼了。
三、第三方庫? BLESSED for Android?的使用
? https://github.com/weliem/blessed-android
下面進入具體的擼代碼環節
安裝 gradle file加入
allprojects {repositories {...maven { url 'https://jitpack.io' }} }dependencies {implementation 'com.github.weliem:blessed-android:2.0.6' }掃描設備
BluetoothCentralManager central = new BluetoothCentralManager(AppContext.baseAppContext,bluetoothCentralManagerCallback,new Handler(Looper.getMainLooper())); central.scanForPeripherals();bluetoothCentralManagerCallback是掃描回調方法,重要的有下面三個
//發現了一個設備 @Override public void onDiscoveredPeripheral(BluetoothPeripheral peripheral, ScanResult scanResult) //連接設備 @Override public void onConnectedPeripheral(BluetoothPeripheral peripheral) //設備斷開 @Override public void onDisconnectedPeripheral(BluetoothPeripheral peripheral, HciStatus status)發現設備后onDiscoveredPeripheral,連接設備,停止掃描 。bluetoothPeripheralCallback?為設備回調,用于接受通知
central.autoConnectPeripheral(peripheral, bluetoothPeripheralCallback); central.stopScan();onConnectedPeripheral連接后查詢提供的服務及特性
Log.i("BLE","onConnectedPeripheral"); List<BluetoothGattService> serviceList = peripheral.getServices(); for (int i = 0; i < serviceList.size(); i++) {Log.i("BLE", "Service: " + serviceList.get(i).getUuid());if(serviceList.get(i).getUuid().toString().equals("6e400001-b5a3-f393-e0a9-e50e24dcca9e")){List<BluetoothGattCharacteristic> list= serviceList.get(i).getCharacteristics();for (int j = 0; j < list.size(); j++) {Log.i("BLE", "Characteristic: " + list.get(j).getUuid());}} }onConnectedPeripheral后,對特性開啟通知,接受掃碼結果,服務的和特性的UUID,需要對應填寫,掃碼結果是以通知信息返回的。
BluetoothGattCharacteristic currentTimeCharacteristic = peripheral.getCharacteristic(SERVICE_UUID, CURRENT_TIME_CHARACTERISTIC_UUID); if (currentTimeCharacteristic != null) {//開啟通知peripheral.setNotify(currentTimeCharacteristic, true); } //與設備通信需要創建綁定 boolean bret= peripheral.createBond();斷開重連可以在onDisconnectedPeripheral中處理
接收掃碼結果 在設備回調類 bluetoothPeripheralCallback中的下列方法處理。其中value為掃到的二維碼值?
@Override public void onCharacteristicUpdate(@NonNull BluetoothPeripheral peripheral, @NonNull byte[] value, @NonNull BluetoothGattCharacteristic characteristic, @NonNull GattStatus status)另:
- 中文編碼通常為GBK或者UTF8,需要猜測判斷,最后附了個工具函數
- 因為BLE默認數據包較短,對大量數據,會拆分多次發送,onCharacteristicUpdate會被調用多次,需要將value拼接后,進行字符編碼判斷處理。
isUtf8
public static Boolean isUtf8(byte[] buffer) {boolean isUtf8 = true;int end = buffer.length;for (int i = 0; i < end; i++) {byte temp = buffer[i];if ((temp & 0x80) == 0) {// 0xxxxxxxcontinue;} else if ((temp & 0xC0) == 0xC0 && (temp & 0x20) == 0) {// 110xxxxx 10xxxxxxif (i + 1 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0) {i = i + 1;continue;}} else if ((temp & 0xE0) == 0xE0 && (temp & 0x10) == 0) {// 1110xxxx 10xxxxxx 10xxxxxxif (i + 2 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0&& (buffer[i + 2] & 0x80) == 0x80 && (buffer[i + 2] & 0x40) == 0) {i = i + 2;continue;}} else if ((temp & 0xF0) == 0xF0 && (temp & 0x08) == 0) {// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxif (i + 3 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0&& (buffer[i + 2] & 0x80) == 0x80 && (buffer[i + 2] & 0x40) == 0&& (buffer[i + 3] & 0x80) == 0x80 && (buffer[i + 3] & 0x40) == 0) {i = i + 3;continue;}}isUtf8 = false;break;}return isUtf8;}isUtf8總結
以上是生活随笔為你收集整理的Android BLE 蓝牙开发-扫码枪集成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【华为AI比赛】广告信息流跨域CTR预估
- 下一篇: Redis面试经典问题