详解蓝牙BluetoothGattCallback用法之BLE数据发送

详解蓝牙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,因为底层硬件要求的数据帧为这种格式,具体发送的时候要按照具体情况来。
先写这么多,接收数据请看下一篇。

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值