4203|2

2618

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

详解蓝牙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,因为底层硬件要求的数据帧为这种格式,具体发送的时候要按照具体情况来。


此帖出自无线连接论坛

最新回复

谢谢分享,好像不同安卓系统ble代码兼容性非常不理想?  详情 回复 发表于 2019-4-30 16:22
点赞 关注(1)
 

回复
举报

244

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
认真看完了,写的真好,就喜欢你这样的帖子,全是干货,另外请问接收数据的时候,收到哪个buffer里面了,怎么没看到?谢谢。
此帖出自无线连接论坛
 
 

回复

1301

帖子

0

TA的资源

纯净的硅(中级)

板凳
 
谢谢分享,好像不同安卓系统ble代码兼容性非常不理想?
此帖出自无线连接论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表