I am developing an chat application using BLE Android to iOS, Right now i am using below two libraries for the reference
https://github.com/izumin5210/Bletia
https://github.com/captain-miao/bleYan
Issue that i am facing is BLECallback in ble central device (Android) are not called when peripheral device write any characteristics.
My Callback Code
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
BleLog.i(TAG, "onConnectionStateChange: State = " + BleUtils.getBleConnectStatus(status)
+ " newState = " + BleUtils.getBleConnectStatus(newState));
if (newState == BluetoothProfile.STATE_CONNECTED) {
updateState(BleConnectState.CONNECTED);
//开始发现服务
BleLog.i(TAG, "gatt.discoverServices()");
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_CONNECTING) {
updateState(BleConnectState.CONNECTING);
} else if (newState == BluetoothProfile.STATE_DISCONNECTING) {
updateState(BleConnectState.DISCONNECTING);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
//断开了,需要做什么处理?
sIsWriting = false;
sWriteQueue.clear();
updateState(BleConnectState.DISCONNECTED);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
onDiscoverServices(gatt);
//需要返回 gatt
updateState(BleConnectState.SERVICE_IS_DISCOVERED);
} else {
BleUtils.refreshDeviceCache(mGatt);
//失败 需要做何处理 129
if(mState != BleConnectState.SERVICE_IS_NOT_DISCOVERED) {
updateState(mState);
}
}
//MSG_BLE_ID_SERVICES_DISCOVERED
Message msg = Message.obtain();
msg.what = BleConstants.MSG_BLE_ID_SERVICES_DISCOVERED;
msg.arg1 = status;
msg.obj = gatt;
notifyAllBleClients(msg);
BleLog.i(TAG, "onServicesDiscovered: " + BleUtils.getGattStatus(status));
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
BleLog.i(TAG, "onCharacteristicWrite: " + BleUtils.getGattStatus(status));
UUID uuid = characteristic.getUuid();
sendBleMessage(BleConstants.MSG_BLE_ID_CHARACTERISTIC_WRITE, status, uuid);
onNextWrite();
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {
BleLog.i(TAG, "onDescriptorWrite: " + BleUtils.getGattStatus(status));
UUID uuid = descriptor.getUuid();
sendBleMessage(BleConstants.MSG_BLE_ID_DESCRIPTOR_WRITE, status, uuid);
onNextWrite();
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
final byte[] data = characteristic.getValue();
BleLog.i(TAG, "onCharacteristicChanged: " + HexUtil.encodeHexStr(data));
UUID uuid = characteristic.getUuid();
sendBleMessage(BleConstants.MSG_BLE_ID_CHARACTERISTIC_NOTIFICATION, BluetoothGatt.GATT_SUCCESS, data, uuid);
onNextWrite();
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
final byte[] data = characteristic.getValue();
System.out.println(TAG +" onCharacteristicRead: " + data);
if(data != null) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
final String values = stringBuilder.toString();
BleLog.i(TAG, "onCharacteristicRead: " + new String(data));
}else{
BleLog.i(TAG, " onCharacteristicRead: " + "NULL");
}
UUID uuid = characteristic.getUuid();
sendBleMessage(BleConstants.MSG_BLE_ID_CHARACTERISTIC_READ, status, data, uuid);
onNextWrite();
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
final byte[] data = descriptor.getValue();
if(data != null) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
final String values = stringBuilder.toString();
BleLog.i(TAG, "onDescriptorRead: " + new String(data, Charset.defaultCharset()));
}else{
BleLog.i(TAG, " onDescriptorRead: " + "NULL");
}
UUID uuid = descriptor.getUuid();
sendBleMessage(BleConstants.MSG_BLE_ID_DESCRIPTOR_READ, status, data, uuid);
onNextWrite();
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
BleLog.i(TAG, "onReliableWriteCompleted: " + BleUtils.getGattStatus(status));
Message msg = Message.obtain();
msg.what = BleConstants.MSG_BLE_ID_RELIABLE_WRITE_COMPLETED;
msg.arg1 = status;
notifyAllBleClients(msg);
onNextWrite();
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
BleLog.i(TAG, "onReadRemoteRssi: " + rssi + " status:" + BleUtils.getGattStatus(status));
Message msg = Message.obtain();
msg.what = BleConstants.MSG_BLE_ID_READ_REMOTE_RSSI;
msg.arg1 = status;
msg.arg2 = rssi;
notifyAllBleClients(msg);
onNextWrite();
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
BleLog.i(TAG, "onMtuChanged: " + BleUtils.getGattStatus(status));
Message msg = Message.obtain();
msg.what = BleConstants.MSG_BLE_ID_MTU_CHANGED;
msg.arg1 = status;
msg.arg2 = mtu;
notifyAllBleClients(msg);
onNextWrite();
}
};
iOS Notify Code
if (myPeripheral.connectedToPeer)
{
CBCharacteristic *peerAvailable = [myPeripheral findCharacteristicFromUUID:myPeripheral.notifyPeerAvailableUUID];
if (peerAvailable && !peerAvailable.isNotifying) {
[myPeripheral.cbPeripheral setNotifyValue:YES forCharacteristic:peerAvailable];
}
CBCharacteristic *peerReceiveMessage = [myPeripheral findCharacteristicFromUUID:myPeripheral.peerSendToCentralFromPeripheralUUID];
if (peerReceiveMessage && !peerReceiveMessage.isNotifying) {
[myPeripheral.cbPeripheral setNotifyValue:YES forCharacteristic:peerReceiveMessage];
}
}
The peripheral device should notify that the characteristic has changed by using bluetoothGattServer.notifyCharacteristicChanged
The Android central device should subscribe the notification.
if (characteristic != null) {
//SetNotification
Log.i(TAG, "SetNotification");
gatt.setCharacteristicNotification(characteristic, true);
for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
}