详解蓝牙BluetoothGattCallback用法之BLE数据发送
看了好多网上的例子,感觉都是一大抄,都是些什么官方demo,用的都是跟别人一样的广播啊,服务啊,什么鬼,看起来高大上其实没什么卵用的东西,都没有理解到BluetoothGattCallback这个函数里面发送数据与接收数据的精髓,扯一堆东西,结果最后还是不能用,接下来我就直接开始撸干货了,什么蓝牙扫描,蓝牙连接,我就先不说了,直接来重点。
首先把BluetoothGattCallback回调函数上了再说
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {//连接状态改变
Log.e("BluetoothGatt中中中", "连接状态:" + newState);
/**
* 连接状态:
* * The profile is in disconnected state *public static final int STATE_DISCONNECTED = 0;
* * The profile is in connecting state *public static final int STATE_CONNECTING = 1;
* * The profile is in connected state *public static final int STATE_CONNECTED = 2;
* * The profile is in disconnecting state *public static final int STATE_DISCONNECTING = 3;
*
*/
if (BluetoothGatt.STATE_CONNECTED == newState) {
Log.e("onConnec中中中", "连接成功:");
gatt.discoverServices();//必须有,可以让onServicesDiscovered显示所有Services
tx_display.append("连接成功");
Toast.makeText(mContext, "连接成功", Toast.LENGTH_SHORT).show();
}else if (BluetoothGatt.STATE_DISCONNECTED == newState){
Log.e("断开 中中中", "断开连接:");
Toast.makeText(mContext, "断开连接", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {//发现服务,在蓝牙连接的时候会调用
List<BluetoothGattService> list = mBluetoothGatt.getServices();
for (BluetoothGattService bluetoothGattService:list){
String str = bluetoothGattService.getUuid().toString();
Log.e("onServicesDisc中中中", " :" + str);
List<BluetoothGattCharacteristic> gattCharacteristics = bluetoothGattService
.getCharacteristics();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
Log.e("onServicesDisc中中中", " :" + gattCharacteristic.getUuid());
if("0000ffe1-0000-1000-8000-00805f9b34fb".equals(gattCharacteristic.getUuid().toString())){
linkLossService=bluetoothGattService;
alertLevel=gattCharacteristic;
Log.e("daole",alertLevel.getUuid().toString());
}
}
}
enableNotification(true,gatt,alertLevel);//必须要有,否则接收不到数据
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
Log.e("onCharacteristicRead中", "数据接收了哦"+bytesToHexString(characteristic.getValue()));
}
/**
* 发送数据后的回调
* @param gatt
* @param characteristic
* @param status
*/
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {//发送数据时调用
Log.e("onCharacteristicWrite中", "数据发送了哦");
Log.e("onCharacteristicWrite中", bytesToHexString(characteristic.getValue()));
if(status == BluetoothGatt.GATT_SUCCESS){//写入成功
Log.e("onCharacteristicWrite中", "写入成功");
tx_display.append("写入成功");
}else if (status == BluetoothGatt.GATT_FAILURE){
Log.e("onCharacteristicWrite中", "写入失败");
}else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
Log.e("onCharacteristicWrite中", "没权限");
}
}
@Override
public void onDescriptorRead(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {//descriptor读
//Log.e("onCDescripticRead中", "数据接收了哦"+bytesToHexString(characteristic.getValue()));
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {// Characteristic 改变,数据接收会调用
Log.e("CharacteristicChanged中", "数据接收了哦"+bytesToHexString(characteristic.getValue()));
tx_receive.append(bytesToHexString(characteristic.getValue()) + "\n");
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {//descriptor写
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { //读Rssi
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
}
};
先要定义mBluetoothGatt
private BluetoothGatt mBluetoothGatt;
然后在连接蓝牙的时候要写上这个回调函数,这样会把蓝牙的相关信息传到回调函数,才能进行接下来的数据发送与接收。
/**
* 蓝牙连接
* @param device
*/
public void connect(BluetoothDevice device) {
Log.e("connect中中中","开始连接:");
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
}
对BluetoothGattCallback中的 onConnectionStateChange的分析
很明显这个是对蓝牙连接状态的回调看蓝牙是否连接成功。相信看上面的源码的注释大家都能看懂,这里就不多做解释。
对BluetoothGattCallback中的 onServicesDiscovered的分析
这个是重点了,很重要的地方你这里不写好,就不能发送和接收数据了,我们进行详细地讲解
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {//发现服务,在蓝牙连接的时候会调用
List<BluetoothGattService> list = mBluetoothGatt.getServices();
for (BluetoothGattService bluetoothGattService:list){
String str = bluetoothGattService.getUuid().toString();
Log.e("onServicesDisc中中中", " :" + str);
List<BluetoothGattCharacteristic> gattCharacteristics = bluetoothGattService
.getCharacteristics();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
Log.e("onServicesDisc中中中", " :" + gattCharacteristic.getUuid());
if("0000ffe1-0000-1000-8000-00805f9b34fb".equals(gattCharacteristic.getUuid().toString())){
linkLossService=bluetoothGattService;
alertLevel=gattCharacteristic;
Log.e("daole",alertLevel.getUuid().toString());
}
}
}
enableNotification(true,gatt,alertLevel);//必须要有,否则接收不到数据
//Log.e("onServicesDisc中中中", " :" + mBluetoothGatt.getServices().toString());
}
先把这个ble的所有服务遍历,然后把所有服务的Characteristic遍历,目的其实就是为了
linkLossService=bluetoothGattService;
alertLevel=gattCharacteristic;
这两句,把需要的服务中的Characteristic找到,为什么呢,因为发送数据需要,如果你不知道你的设备中可读写的Characteristic的uuid你需要先知道uuid,了解uuid的知识网上有很多,可以自行查阅,而且讲得也特别详细。
既然已经找到需要的Characteristic,那么就可以用于发送数据了。
/**
* 向蓝牙发送数据
*/
public void dataSend(){
//byte[] send={(byte) 0xaa,0x01,0x01,(byte)0x81,(byte) 0xff};
byte[] send = new byte[20];
send = hexStringToBytes(et_send.getText().toString());
byte[] sendData=new byte[send.length+2];
sendData[0]=(byte) 0xaa;
sendData[sendData.length-1]=(byte) 0xff;
for(int i=1;i<sendData.length-1;i++){
sendData[i]=send[i-1];
}
Log.e("dataSend", bytesToHexString(sendData));
Log.e("dataSend", linkLossService +"");
alertLevel.setValue(sendData);
boolean status = mBluetoothGatt.writeCharacteristic(alertLevel);
Log.e("dataSend", status+"");
}
因为硬件设备接收的都是byte类型的数据,所以我们发送的也就是byte,我这里是从editview中获取数据,然后加工成byte类型。这里我在每条指令前加了0xaa,末尾加了0xff,因为底层硬件要求的数据帧为这种格式,具体发送的时候要按照具体情况来。
先写这么多,接收数据请看下一篇。