Android BLE gattcallback 读写问题
Android BLE gattcallback issue on read and write
上周我陷入了一个奇怪的问题,它很快就会让我发疯,Whosebug 是我最后的希望。
我只是简单地写了一段代码来与 BLE 设备进行通信。起初我只是写一个关于特征的值。
public void writeEnableCredentials(String keysFn) {
if ( sGattCharList != null) {
Log.i("Callback WEC Method: ", "Start!!!/n" );
String val = keysFn.substring(0, 2);
String val2 = keysFn.substring(2, 4);
int val_1 = Integer.parseInt(val);
int val_2 = Integer.parseInt(val2);
byte[] rk_byte_Value = new byte[1];
final byte[] rk_byte_Value_2 = new byte[1];
rk_byte_Value[0] = (byte)(val_1 & 0xFF);
rk_byte_Value_2[0] = (byte)(val_2 & 0xFF);
sGattCharList.get(1).setValue(rk_byte_Value);
boolean ok = sBluetoothGatt.writeCharacteristic(sGattCharList.get(1));
Log.i("Callback WEC Method: ", "1 Verified = " + ok);
if(ok) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
sGattCharList.get(2).setValue(rk_byte_Value_2);
boolean ok = sBluetoothGatt.writeCharacteristic(sGattCharList.get(2));
Log.i("Callback WEC Method: ", "2 Verified = " + ok);
}
}, 100);
}
} else {
Toast.makeText(activity, "Wait for services", Toast.LENGTH_SHORT).show();
}
Log.i("Callback WEC Method: ", "Stop!!!/n" );
}
BluetoothGattCallback 方法如下:
private final BluetoothGattCallback sGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i("CallbackGatt","Connecting with " + sDevice.getsMac());
sBluetoothGatt.discoverServices();
}
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
sBluetoothGatt.close();
Log.i("CallbackGatt", "Disconnected from GATT server.");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
services_List = gatt.getServices();
sGattCharList = services_List.get(3).getCharacteristics();
Log.i("CallbackGatt","Characteristic List Found: " + sGattCharList);
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if(status == BluetoothGatt.GATT_SUCCESS) {
byte[] bytes = characteristic.getValue();
System.out.println("ON Characteristic WRITE Callback: " + characteristic.getUuid()+" value: "+bytes);
}
}
};
问题: 此代码在 API>22 上运行良好。 BUT API<=22 BluetoothGattCallback 无法正常工作,有时会收到回调,但在 运行 再次构建相同的版本后,我没有收到回调,特征也没有写了。
调试日志 运行 基于 5.1.1
*Trying to write 1st time*
07-04 00:29:28.370 19270-19270/com.example.xxx.xxxx/Callback WEC Method:: Start!!!/n
07-04 00:29:28.371 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:29:28.372 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:29:28.472 9115-9185/? E/bt-btif: already has a pending command!!
07-04 00:29:28.472 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:28.474 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
*Trying to write 2nd time*
07-04 00:29:33.371 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Start!!!/n
07-04 00:29:33.371 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: GKI_exception(): Task State Table
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [0] task name [BTU] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [1] task name [BTIF] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [2] task name [A2DP-MEDIA] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: GKI_exception 65532 Freeing Linked Buf
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: * GKI_exception(): 65532 Freeing Linked Buf
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.372 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:29:33.373 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:29:33.474 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:33.474 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: GKI_exception(): Task State Table
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [0] task name [BTU] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [1] task name [BTIF] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [2] task name [A2DP-MEDIA] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: GKI_exception 65532 Freeing Linked Buf
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: * GKI_exception(): 65532 Freeing Linked Buf
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/RIDLSQL.cpp:1920: GetTransState() EBADF
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/MainCore.cpp:1346: Failed to get TransState, rc
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/RIDLSQL.cpp:1920: GetTransState() EBADF
杀死应用=>清除缓存=>启动应用=>建立连接=>尝试写入=>杀死应用
在执行了 4 次该过程后,我终于收到了回调:D
07-04 00:34:39.144 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: Start!!!/n
07-04 00:34:39.147 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:34:39.147 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:34:39.233 26148-26166/com.example.xxx.xxxx I/System.out: ON Characteristic WRITE Callback: 0000fff2-0000-1000-8000-00805f9b34fb
07-04 00:34:39.247 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
07-04 00:34:39.331 26148-26165/com.example.xxx.xxxx I/System.out: ON Characteristic WRITE Callback: 0000fff3-0000-1000-8000-00805f9b34fb
如果你们需要任何其他详细信息,请询问。另外请告诉我什么是:E/GKI_LINUX:GKI_exception,谢谢。
您需要等待写入回调才能发出新操作。简单地等待 100 毫秒永远不能保证工作,因为它可能需要更长的时间才能获得回调。
上周我陷入了一个奇怪的问题,它很快就会让我发疯,Whosebug 是我最后的希望。 我只是简单地写了一段代码来与 BLE 设备进行通信。起初我只是写一个关于特征的值。
public void writeEnableCredentials(String keysFn) {
if ( sGattCharList != null) {
Log.i("Callback WEC Method: ", "Start!!!/n" );
String val = keysFn.substring(0, 2);
String val2 = keysFn.substring(2, 4);
int val_1 = Integer.parseInt(val);
int val_2 = Integer.parseInt(val2);
byte[] rk_byte_Value = new byte[1];
final byte[] rk_byte_Value_2 = new byte[1];
rk_byte_Value[0] = (byte)(val_1 & 0xFF);
rk_byte_Value_2[0] = (byte)(val_2 & 0xFF);
sGattCharList.get(1).setValue(rk_byte_Value);
boolean ok = sBluetoothGatt.writeCharacteristic(sGattCharList.get(1));
Log.i("Callback WEC Method: ", "1 Verified = " + ok);
if(ok) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
sGattCharList.get(2).setValue(rk_byte_Value_2);
boolean ok = sBluetoothGatt.writeCharacteristic(sGattCharList.get(2));
Log.i("Callback WEC Method: ", "2 Verified = " + ok);
}
}, 100);
}
} else {
Toast.makeText(activity, "Wait for services", Toast.LENGTH_SHORT).show();
}
Log.i("Callback WEC Method: ", "Stop!!!/n" );
}
BluetoothGattCallback 方法如下:
private final BluetoothGattCallback sGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i("CallbackGatt","Connecting with " + sDevice.getsMac());
sBluetoothGatt.discoverServices();
}
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
sBluetoothGatt.close();
Log.i("CallbackGatt", "Disconnected from GATT server.");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
services_List = gatt.getServices();
sGattCharList = services_List.get(3).getCharacteristics();
Log.i("CallbackGatt","Characteristic List Found: " + sGattCharList);
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if(status == BluetoothGatt.GATT_SUCCESS) {
byte[] bytes = characteristic.getValue();
System.out.println("ON Characteristic WRITE Callback: " + characteristic.getUuid()+" value: "+bytes);
}
}
};
问题: 此代码在 API>22 上运行良好。 BUT API<=22 BluetoothGattCallback 无法正常工作,有时会收到回调,但在 运行 再次构建相同的版本后,我没有收到回调,特征也没有写了。
调试日志 运行 基于 5.1.1
*Trying to write 1st time*
07-04 00:29:28.370 19270-19270/com.example.xxx.xxxx/Callback WEC Method:: Start!!!/n
07-04 00:29:28.371 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:29:28.372 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:29:28.472 9115-9185/? E/bt-btif: already has a pending command!!
07-04 00:29:28.472 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:28.474 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
*Trying to write 2nd time*
07-04 00:29:33.371 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Start!!!/n
07-04 00:29:33.371 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: GKI_exception(): Task State Table
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [0] task name [BTU] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [1] task name [BTIF] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [2] task name [A2DP-MEDIA] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: GKI_exception 65532 Freeing Linked Buf
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: * GKI_exception(): 65532 Freeing Linked Buf
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.372 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:29:33.373 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:29:33.474 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:33.474 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: GKI_exception(): Task State Table
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [0] task name [BTU] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [1] task name [BTIF] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [2] task name [A2DP-MEDIA] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: GKI_exception 65532 Freeing Linked Buf
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: * GKI_exception(): 65532 Freeing Linked Buf
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/RIDLSQL.cpp:1920: GetTransState() EBADF
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/MainCore.cpp:1346: Failed to get TransState, rc
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/RIDLSQL.cpp:1920: GetTransState() EBADF
杀死应用=>清除缓存=>启动应用=>建立连接=>尝试写入=>杀死应用
在执行了 4 次该过程后,我终于收到了回调:D
07-04 00:34:39.144 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: Start!!!/n
07-04 00:34:39.147 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:34:39.147 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:34:39.233 26148-26166/com.example.xxx.xxxx I/System.out: ON Characteristic WRITE Callback: 0000fff2-0000-1000-8000-00805f9b34fb
07-04 00:34:39.247 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
07-04 00:34:39.331 26148-26165/com.example.xxx.xxxx I/System.out: ON Characteristic WRITE Callback: 0000fff3-0000-1000-8000-00805f9b34fb
如果你们需要任何其他详细信息,请询问。另外请告诉我什么是:E/GKI_LINUX:GKI_exception,谢谢。
您需要等待写入回调才能发出新操作。简单地等待 100 毫秒永远不能保证工作,因为它可能需要更长的时间才能获得回调。