详解蓝牙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 list = mBluetoothGatt.getServices(); for (BluetoothGattService bluetoothGattService:list){ String str = bluetoothGattService.getUuid().toString(); Log.e("onServicesDisc中中中", " :" + str); List 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 list = mBluetoothGatt.getServices(); for (BluetoothGattService bluetoothGattService:list){ String str = bluetoothGattService.getUuid().toString(); Log.e("onServicesDisc中中中", " :" + str); List 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=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,因为底层硬件要求的数据帧为这种格式,具体发送的时候要按照具体情况来。
|