BLE 外围设备和 BLE 中央设备
BLE Peripheral & BLE Central
我正在使用 BLE Android 到 iOS 开发一个聊天应用程序,
现在我正在使用以下两个库作为参考
https://github.com/izumin5210/Bletia
https://github.com/captain-miao/bleYan
我面临的问题是当外围设备写入任何特征时,中央设备 (Android) 中的 BLECallback 不会被调用。
我的回调代码
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 通知代码
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];
}
}
外围设备应使用bluetoothGattServer.notifyCharacteristicChanged
通知特性已更改
Android 中央设备应订阅通知。
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);
}
在peripheral中,你写的Characteristic应该有NOTIFY属性,central应该使用setCharacteristicNotification函数来监听characteristic的变化。当值改变时,会触发onCharacteristicChanged回调。
我正在使用 BLE Android 到 iOS 开发一个聊天应用程序, 现在我正在使用以下两个库作为参考
https://github.com/izumin5210/Bletia
https://github.com/captain-miao/bleYan
我面临的问题是当外围设备写入任何特征时,中央设备 (Android) 中的 BLECallback 不会被调用。
我的回调代码
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 通知代码
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];
}
}
外围设备应使用bluetoothGattServer.notifyCharacteristicChanged
Android 中央设备应订阅通知。
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);
}
在peripheral中,你写的Characteristic应该有NOTIFY属性,central应该使用setCharacteristicNotification函数来监听characteristic的变化。当值改变时,会触发onCharacteristicChanged回调。