BlueToothBLE開發

參考資料:https://github.com/Charon1997/BleCar
api5.0與之前版本的ble問題
主要參考:
搜索:MainActivity
連接:ControlActivity+BluetoothLeService

這次要做一個BLE的小功能,給一塊Nordic_UART的板子做對接。
先頭說要接入Nordic的sdk,後來找了BleCar的資料發現沒有必要,直接可以發現,和讀取。
在和我的ios同時對比中發現,ios發現後默認就可以讀出設備上的value,而Android則需要手動向設備發起查詢
參照上述參考資料可以順利完成連接,然後讀數難住了,
https://www.cnblogs.com/cxk1995/p/5693979.html
看了幾篇帖子,都大同小異,我不太明白髮送時的BluetoothGattCharacteristic是怎麼來的,畢竟發現的時候BluetoothGattCharacteristic可發現了五個,你讓我給誰發?
於是實踐出真知,關於收發的部分我修改了一下,在Service中提了一個characteristic的List,又包裝了兩個方法

public List<BluetoothGattCharacteristic> characteristics = new ArrayList<>();
public void writeCharacteristic(String msg){
            Log.d(TAG, "writeCharacteristic has characteristics"+characteristics.size());
        for(int i=0;i<characteristics.size();i++){
            BluetoothGattCharacteristic cc = characteristics.get(i);
            cc.setValue(msg);
            writeCharacteristic(cc);
        }

    }
    public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        } else mBluetoothGatt.writeCharacteristic(characteristic);

    }

    public void readCharacteristic(){
        Log.d(TAG, "readCharacteristic has characteristics"+characteristics.size());

        for(BluetoothGattCharacteristic characteristic:characteristics){
            readCharacteristic(characteristic);
        }
    }
    public void readCharacteristic(BluetoothGattCharacteristic characteristic){
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        } else mBluetoothGatt.readCharacteristic(characteristic);
    }

讀取結果爲:
這裏寫圖片描述

黃色爲readCharacteristic(),紅色爲writeCharacteristic(msg)
在onServicesDiscovered結束時,characteristics的個數一共是5個,打印log也能夠看出來,但最後能夠做讀取修改的只有一個,這個大概是和硬件設置有關,不能寫的也沒有回調。

另外還要說明一點,state=133的問題除了最初鏈接的時候發生過,在writeCharacteristic的數據過長時也發生了。

error code對照
ASCII對照表
關於Bluetooth包中類的一些解釋

android這邊調試ble的時候有幾個問題需要說明
1是不知道要給5個特徵裏哪一個發送,直到看了源碼發現:
if((gattCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)>0) {
//true爲符合讀寫條件的
}
這個判斷在write裏面也有,但是我不知道呀所以當時就循環發了。

2、是Android這邊由於google已經封裝好了不用像ios一樣先把string轉成16進制ascii碼再轉成NSDATA,我們這邊只要String或者String.getBytes()就搞定了

3、註冊監聽
當你給藍牙寫了一條數據之後,不用起timer輪詢readCharacteristic,直接註冊監聽在Gatta的CallBack裏等

onCharacteristicChanged被調用,然而我做的時候參考了大部分帖子都是這麼說的:
boolean isEnableNotification = 
    mBluetoothGatt.setCharacteristicNotification(characteristic, true);
    Log.d(TAG, "Bluetooth setCharacteristicNotification:"+isEnableNotification);
    //這裏是設置可接收的屬性,沒有下面這段onCharacteristicChanged不會被調用
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
       UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
       if (descriptor != null) {
           descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
           mBluetoothGatt.writeDescriptor(descriptor);
       }

請問SampleGattAttributes是個啥?
然後有看到人家說UUID_CCC,看了好幾篇帖子,覺得UUID_CCC是個固定的UUID:”00002902-0000-1000-8000-00805f9b34fb”
這個uuid的descriptor 是在characteristic裏面的,然而我write的characteristic.getDescriptors().size()=0一下就沒得玩了。
找了幾篇不錯的帖子解析帖子去說這個

在僵持不下之時我靈光一閃,我可是有三條service呀,會不會是其他service下的特徵有descriptor呢?於是通過輪詢我發現和write那條characteristic同級別的service裏另一條characteristic中有descriptor
於是打印發現descriptor uuid:00002902-0000-1000-8000-00805f9b34fb
眼熟不眼熟,然後修改了監聽的characteristic,這麼一運行,就返回來了
/BlueToothService: onCharacteristicChanged characteristic UUID:6e400003-b5a3-f393-e0a9-e50e24dcca9e characteristic:$LockOpened

4、發送順序
mBluetoothGatt.writeCharacteristic(characteristic);要先於mBluetoothGatt.setCharacteristicNotification
爲什麼我不清楚,但順序反了就接不到了╮(╯▽╰)╭

參考

這裏還想說,有一本書叫《ANDROID物聯網開發從入門到實戰》裏面從第四章開始看就可以了,是講BLE藍牙的,比零散的博客更系統的講述BLE和傳統藍牙的不同,比如其中提到了BLE和NFC的對比,NFC達不到BLE的傳輸速度,雖然它的設置更簡化。
而我覺得比較有價值的是4.5章低功耗藍牙協議棧詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章