Android writeDescriptor接收true时,无法触发Enable onDescriptorWrite
这是我启用特征通知的代码Android writeDescriptor接收true时,无法触发Enable onDescriptorWrite,android,bluetooth-lowenergy,Android,Bluetooth Lowenergy,这是我启用特征通知的代码 private void enableNotification(BluetoothGattCharacteristic characteristic) { boolean s = bluetoothGatt.setCharacteristicNotification(characteristic, true); Log.d(TAG, "enableNotification: setCharacteristicNotification " + s);
private void enableNotification(BluetoothGattCharacteristic characteristic) {
boolean s = bluetoothGatt.setCharacteristicNotification(characteristic, true);
Log.d(TAG, "enableNotification: setCharacteristicNotification " + s);
List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
if (null != descriptors && descriptors.size() > 0) {
for (BluetoothGattDescriptor descriptor : descriptors) {
Log.d(TAG, "enableNotification: " + descriptor.getUuid());
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean s1 = bluetoothGatt.writeDescriptor(descriptor);
Log.d(TAG, "enableNotification: writeDescriptor " + s1);
}
} else {
Log.d(TAG, "enableNotification: descriptors is null");
}
}
正如我们所看到的,writeDescriptor返回true,但onDescriptorWrite()方法不是trigger,BluetoothGatt显示了日志onConnectionUpdated()。如果有人能告诉我为什么我没有触发器。下面是我在BluetoothGattCallback中的onDescriptorWrite代码,如果代码被执行,在任何情况下都会有一些日志
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "onDescriptorWrite: GATT_SUCCESS");
connectCallback.readMeterId();
} else if (status == BluetoothGatt.GATT_FAILURE) {
Log.d(TAG, "onDescriptorWrite: GATT_FAILURE");
} else {
Log.d(TAG, "onDescriptorWrite: something");
}
}
我的BluetoothGattCallback代码如下
private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
bluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
gatt.close();
Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
} else {
Log.d(TAG, "onConnectionStateChange: FAIL");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
//print all the service and characteristic
for (BluetoothGattService service : bluetoothGatt.getServices()) {
Log.d(TAG, "onServicesDiscovered: service ->" + service.getUuid());
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
Log.d(TAG, "onServicesDiscovered: characteristic ->" + characteristic.getUuid());
}
}
BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(BleConstant.SERVICE_UUID.SERVICE));
characteristics = service.getCharacteristics().subList(0, 2);
// enableNotification(characteristics.get(0));
for (BluetoothGattCharacteristic characteristic : characteristics) {
Log.d(TAG, "onServicesDiscovered: Properties -> " + characteristic.getUuid() + " " + characteristic.getProperties());
enableNotification(characteristic);
}
} else {
Log.d(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.d(TAG, "onCharacteristicChanged: " + Arrays.toString(characteristic.getValue()));
Log.d(TAG, "onCharacteristicChanged: string -> " + characteristic.getStringValue(0));
String callbackDataString = characteristic.getStringValue(0);
byte[] callbackDataByte = characteristic.getValue();
// boolean checkData = CRC16Util.getInstance().verification(callbackDataString);
dosomething with the response date
if (CRC16Util.getInstance().verification(callbackDataString)) {
connectCallback.crcError();
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d(TAG, "onCharacteristicRead: " + Arrays.toString(characteristic.getValue()));
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d(TAG, "onCharacteristicWrite: " + Arrays.toString(characteristic.getValue()));
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "onDescriptorWrite: GATT_SUCCESS");
connectCallback.readMeterId();
} else if (status == BluetoothGatt.GATT_FAILURE) {
Log.d(TAG, "onDescriptorWrite: GATT_FAILURE");
} else {
Log.d(TAG, "onDescriptorWrite: something");
}
}
};
在这段代码中,connectCallback
是这样一个接口
public interface ConnectCallback {
/**
* It needs to be triggered after notify successful
*/
void readMeterId();
/**
* callback of CRC ERROR
*/
void crcError();
/**
* callback of Transmission completed
*/
void onComplete();
/**
* callback of Read MeterId Error
*/
void onReadMeterIdError();
}
我仅在onDescriptorWrite成功(通知成功)时向ble发送命令
下面是我的连接代码
public boolean connectToDevice(final String address, ConnectCallback connectCallback) {
if (null == bluetoothAdapter || null == address) {
Log.d(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
if (null != bluetoothGatt) {
bluetoothGatt = null;
}
final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.d(TAG, "Device not found. Unable to connect.");
return false;
}
Log.d(TAG, "Trying to create a new connection.");
this.connectCallback = connectCallback;
bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback);
return true;
}
我在服务中编写所有ble代码,并将其用于这样的活动中
private void bindBleService() {
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
BleService.LocalBinder binder = (BleService.LocalBinder) service;
bleService = binder.getService();
if (!bleService.init()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
boolean isConn = bleService.connectToDevice(deviceAddress, new BleService.ConnectCallback() {
@Override
public void readMeterId() {
notifySuccess = true;
runOnUiThread(() -> {
waitBleDialog.setTitle(getString(R.string.edit_read_meter_id));
waitBleDialog.show();
});
bleService.sendDataToBle(READ_METER_ID.OCP);
meterIdUsed.put(READ_METER_ID.OCP, true);
}
@Override
public void crcError() {
if (waitBleDialog.isShowing()) {
waitBleDialog.cancel();
}
runOnUiThread(() -> {
Toast.makeText(BleResultActivity.this, getString(R.string.ble_crc_error), Toast.LENGTH_SHORT).show();
finish();
});
}
@Override
public void onComplete() {
if (recordList.size() == 0) {
if (waitBleDialog.isShowing()) {
waitBleDialog.cancel();
}
runOnUiThread(() -> Toast.makeText(BleResultActivity.this, getString(R.string.edit_no_new_record), Toast.LENGTH_SHORT).show());
recordTestButton.setOnClickListener(v -> runOnUiThread(() -> Toast.makeText(BleResultActivity.this, getString(R.string.edit_no_new_record), Toast.LENGTH_SHORT).show()));
} else {
runOnUiThread(() -> {
recordTestButton.setEnabled(true);
Toast.makeText(BleResultActivity.this, getString(R.string.edit_transmit_finish), Toast.LENGTH_SHORT).show();
});
recordTestButton.setOnClickListener(recordTest);
}
}
@Override
public void onReadMeterIdError() {
boolean haveCommendNotUsed = true;
for (String command : meterIdUsed.keySet()) {
Boolean commandUsed = meterIdUsed.get(command);
if (null == commandUsed) {
commandUsed = false;
}
if (!commandUsed) {
haveCommendNotUsed = true;
bleService.sendDataToBle(command);
meterIdUsed.put(command, true);
break;
} else {
haveCommendNotUsed = false;
}
}
if (!haveCommendNotUsed) {
waitBleDialog.cancel();
runOnUiThread(() -> Toast.makeText(BleResultActivity.this, getString(R.string.edit_read_meter_id_failed), Toast.LENGTH_SHORT).show());
finish();
}
}
});
if (!isConn) {
Log.d(TAG, "onServiceConnected: false");
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
bleService = null;
}
};
final Intent intent = new Intent(this, BleService.class);
bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
}
我现在知道的是,在运行enableNotification()方法和writeDescriptor()返回true之后,onConnectionUpdated()发生了,我失去了连接。onConnectionUpdated()隐藏在源代码中,我不知道它为什么会出现以及如何处理。您的应用程序似乎没有连接到您的设备 要知道连接是否成功,您需要在
onConnectionStateChange()
中检查给定的状态是否等于BluetoothGatt.GATT\u SUCCESS
此外,检查可能的GATT\u连接超时:
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if ((newState == BluetoothProfile.STATE_CONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
bluetoothGatt.discoverServices();
} else if ((newState == BluetoothProfile.STATE_DISCONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
gatt.close();
Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
} else if (status == GATT_CONN_TIMEOUT) {
Log.e(TAG, "GATT_CONN_TIMEOUT !");
} else {
Log.e(TAG, "onConnectionStateChange: FAIL");
}
}
对特征进行写入时是否调用onCharacteristicWrite()?请添加BluetoothGattCallback实现的代码,当onDescriptorWrite没有触发器时,我尝试编写特性,但失败了,onCharacteristicWrite()未被调用。您的外围设备是否确实发送了写入响应?如果没有,Android也会在30秒后自动断开连接。我实际上发送了一个写响应,但没有通知该特征,我的写操作也没有响应。onConnectionUpdated日志会立即触发——不超过一秒钟。这不是重点,在我的代码中,我也有日志,但事实上,这个onConnectionStateChange()方法不是触发器。请在调用bluetoothGattCallback的地方发布代码。connect(bluetoothDevice)对不起,我在长城停了很长时间。我现在仍然有这个问题。我已经添加了我的Bluetooth GattCallback.connect代码。谢谢收看
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if ((newState == BluetoothProfile.STATE_CONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
bluetoothGatt.discoverServices();
} else if ((newState == BluetoothProfile.STATE_DISCONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
gatt.close();
Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
} else if (status == GATT_CONN_TIMEOUT) {
Log.e(TAG, "GATT_CONN_TIMEOUT !");
} else {
Log.e(TAG, "onConnectionStateChange: FAIL");
}
}