[英]Android BLE - Peripheral | onCharacteristicRead return wrong value or part of it (but repeated)
我對這個問題迷失了方向。
事實是,一個發布字符串值的android設備:“ 78d89537-4309-4728-87f6-3ab2bbe231d8”(36個字節)。 我正在使用定義為
anonIdCharacteristic = new BluetoothGattCharacteristic(TippeeBluetoothManager.UUID_READ_CHARACTERISTIC,
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_BROADCAST,
BluetoothGattCharacteristic.PERMISSION_READ );
anonIdCharacteristic.setValue(idToAdvertise);
如您所見,我在“閱讀”模式下投放廣告,沒有通知。
當另一個Android設備連接並嘗試讀取特征時,將調用onCharacteristicRead方法, 但傳遞的值錯誤。 更具體地說是:
“ 78d89537-4309-4728-87f678d89537-4309-4728-87f678d89537-4309-4728-87f6 ...”(600字節)
這是預期值的一部分,但會重復。
如果我將自己放在調試“服務器端”,則可以看到發送的字節數正確。 在調試“客戶端”字節為600
我究竟做錯了什么 ?
提前致謝
----編輯-
我發現了更多信息。
現在,我以新月形偏移量反復調用onCharacteristicReadRequest,這導致了“臟”緩沖區,現在我以這種方式進行響應:
if (BluetoothManager.UUID_READ_CHARACTERISTIC.equals(characteristic.getUuid())) { mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, getStoredValue()); return; }
使用偏移值。 尚無法正常工作,但確實如此。
我不知道該告訴應用程序響應多長時間。
好的,我明白了,所以我會留下我的答復來幫助別人解決我的問題。
正確的解決方案是
@Override
public void onCharacteristicReadRequest(BluetoothDevice device,
int requestId,
int offset,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
Log.i(TAG, "onCharacteristicReadRequest " + characteristic.getUuid().toString());
byte[] fullValue = getStoredValue();
//check
if (offset > fullValue.length) {
mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, new byte[]{0} );
return;
}
int size = fullValue.length - offset;
byte[] response = new byte[size];
for (int i = offset; i < fullValue.length; i++) {
response[i - offset] = fullValue[i];
}
if (MYBluetoothManager.UUID_READ_CHARACTERISTIC.equals(characteristic.getUuid())) {
mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, response);
return;
}
mGattServer.sendResponse(device,
requestId,
BluetoothGatt.GATT_FAILURE,
0,
null);
}
};
回調函數被多次調用,並帶有偏移量,這很明顯。 不清楚的是,我應該用一個包含從該偏移量開始的所有數據的數組作為響應。
所以我首先准備一個包含所有數據的數組。 如果請求的偏移量超出了數據的長度,我只返回一個0字節的數組。
如果不是這樣,那么我將從回調請求的偏移量開始准備原始數組的一部分,直到獲得一些信息為止。 因此,如果數組包含大量信息,則不重要,在第二,第三次回調中,我知道從哪里開始返回數據。
抱歉,如果不清楚,但是啟用日志記錄,您將了解我的意思。
祝大家好運
希望您仍然參與其中,因為我沒有在網上找到任何答案,只能自己“挖土”。
因此,我將嘗試將其分解:
假設我們已經在兩個android BLE設備(中央和外圍設備)之間建立了連接,
當BLE中央設備發出針對給定特性的characterRead(...)請求時,將以相關特性作為參數在外圍設備中調用onReadCharacteristic(...)回調。 正確的方法是發出sendResponse(...)方法,將值作為中心讀取的有用值(外圍設備實際要回答的內容)。 因此,正如我所見,您對這種方法非常正確,一切都很好。
Give鏈接的MTU大小是默認值-20個字節。(實際上為23個字節,但對於GATT協議,我們需要3個字節)。因此,任何大於20個字節的緩沖區都將被android拆分為塊(碎片)。 您在這里有幾種選擇:
2.1。 了解如何使用給定的android機制工作,並根據偏移量發送相應的代碼塊。
2.2。 使用來自中央的requestMtu(...)API更改鏈接的MTU大小,以便它可以支持更大的消息。
2.3。 知道鏈接的MTU,並自己建立分段機制(每次調用都會使偏移量始終為0)。
綜上所述,android具有您不知道的碎片化機制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.