Android BLE 讀寫開(kāi)發(fā)回顧
這里主要記錄BLE的通訊方面的筆記
1.發(fā)現(xiàn)BluetoothGattService
回調(diào)
BLE 調(diào)用gatt.connect()
連接成功之后調(diào)用:
gatt.discoverServices()
觸發(fā)回調(diào)void onServicesDiscovered(BluetoothGatt gatt, int status)
通過(guò)硬件規(guī)定的uuid
獲取對(duì)應(yīng)的BluetoothGattService
:
BluetoothGattService service = gatt.getService(mServiceUuid);
在BluetoothGattService
中包含一個(gè)或多個(gè)BluetoothGattCharacteristic
看疗,這些特征字將是后續(xù)用來(lái)讀寫數(shù)據(jù)的載體澡屡,而
通過(guò)硬件給定的uuid
篩選出對(duì)應(yīng)的特征字草讶,譬如有些特征字用于收發(fā)簡(jiǎn)單命令措拇,而有些特征字用于批量發(fā)送數(shù)據(jù):
if (characteristic.getUuid().equals(UUID.fromString(String.format(MEDTRUM_BASE_UUID, MEDTRUM_UUID_CHARACTERISTIC_BULK)))) {
//獲取批量發(fā)送數(shù)據(jù)特征字
mBulkCharacteristics = characteristic;
} else if (characteristic.getUuid().equals(UUID.fromString(String.format(MEDTRUM_BASE_UUID, MEDTRUM_UUID_CHARACTERISTIC_CTRLPT)))) {
//獲取收發(fā)命令特征字
mCommandCharacteristics = characteristic;
}
在拿到特征字之后并不能直接使用旬陡,如果特征字具有通知功能鸭丛,那么還需要對(duì)其進(jìn)行設(shè)置:
Log.d(TAG, "setCharacteristicNotification: "+gatt.setCharacteristicNotification(characteristic, true));
當(dāng)然褥傍,這還不夠裂问,你會(huì)發(fā)現(xiàn)這個(gè)特征字可以正常的發(fā)送數(shù)據(jù)遭顶,但是接受不到返回?cái)?shù)據(jù)张峰,劃重點(diǎn),這里別忘了對(duì)特征字描述符BluetoothGattDescriptor
進(jìn)行設(shè)置:
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
} else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
設(shè)置描述符調(diào)用了mBluetoothGatt.writeDescriptor(descriptor)
方法棒旗,對(duì)應(yīng)的回調(diào)為:
void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)
在回調(diào)中可以對(duì)對(duì)應(yīng)的描述符進(jìn)行驗(yàn)證是否設(shè)置成功喘批,然后就可以正常的使用特征字收發(fā)命令了;
注意,通常BluetoothGattService
并不只包含一個(gè)特征字饶深,而對(duì)特征字的設(shè)置動(dòng)作底層其實(shí)也是一個(gè)寫的命令餐曹,理論上也會(huì)觸發(fā):
void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
但是在開(kāi)發(fā)過(guò)程中通常并不能在這一步接收到回調(diào),這里的原因我還不是很清楚敌厘,大盘ê铮看到請(qǐng),煩請(qǐng)指點(diǎn)一二俱两,嘻嘻饱狂。
既然是寫的操作,就必須遵循串行操作的原則宪彩,有序的寫嗡官,設(shè)置一個(gè)特征字之后延遲一段時(shí)間,再設(shè)置下一個(gè)毯焕。
這里的延遲時(shí)間比較講究衍腥,Android手機(jī)廠家眾多,所以需要給定的延遲時(shí)間也各不相同纳猫,開(kāi)發(fā)經(jīng)驗(yàn)發(fā)現(xiàn)如果間隔時(shí)間超過(guò)250ms SAMSUNG 2s內(nèi)連接不上會(huì)被動(dòng)斷開(kāi),最終測(cè)試結(jié)果定在了700ms,可以適配目前所有的測(cè)試機(jī)型婆咸,如果有大牛有更好的解決辦法,煩請(qǐng)指點(diǎn)一二芜辕,嘻嘻尚骄。
2.讀寫數(shù)據(jù)
在拿到了特征字之后,就可以進(jìn)行讀寫操作了侵续,寫:
if (mCommandCharacteristics != null) {
if (value.length > 0) {
mCommandCharacteristics.setValue(value);
mBluetoothGatt.writeCharacteristic(mCommandCharacteristics);
}
}
發(fā)送數(shù)據(jù)之后倔丈,可以通過(guò)回調(diào):
onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
接收反饋,判斷命令是否發(fā)送成功状蜗。
對(duì)于數(shù)據(jù)的讀取需五,通過(guò)回調(diào):
void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
來(lái)獲取到反饋的內(nèi)容,可以看到這個(gè)回調(diào)中包含了特征字BluetoothGattCharacteristic
很顯然轧坎,我么您可以通過(guò)特征字的uuid
來(lái)判斷反饋的數(shù)據(jù)是命令返回宏邮,或者是通知消息;
注意缸血,在讀寫交互中蜜氨,請(qǐng)一定遵守串行傳輸?shù)臏?zhǔn)則,有序的收發(fā)命令捎泻,避免出現(xiàn)奇奇怪怪的bug;