美文网首页
Android 蓝牙4.0BLE连接

Android 蓝牙4.0BLE连接

作者: Ayugone | 来源:发表于2018-05-17 11:27 被阅读0次

    GATT全称Generic Attribute Profile,中文名叫通用属性协议,它定义了services和characteristic两种东西来完成低功耗蓝牙设备之间的数据传输。它是建立在通用数据协议Attribute Protocol (ATT),之上的,ATT把services和characteristic以及相关的数据保存在一张简单的查找表中,该表使用16-bit的id作为索引。

    一旦两个设备建立了连接,GATT就开始发挥作用,同时意味着GAP协议管理的广播过程结束了。但是必须要知道的是,建立GATT连接必要经过GAP协议。

    最重要的事情,GATT连接是独占的,也就意味着一个BLE周边设备同时只能与一个中心设备连接。一旦周边设备与中心设备连接成功,直至连接断开,它不再对外广播自己的存在,其他的设备就无法发现该周边设备的存在了。

    周边设备和中心设备要完成双方的通信只能通过建立GATT连接的方式。


    1.png

    一个ble蓝牙设备有多个包括多个Profile

    一个Profile中有多个服务Service(通过服务的uuid找到对应的Service)

    一个Service中有多个特征Characteristic(通过特征的uuid找到对应的Characteristic)

    一个Characteristic中包括一个value和多个Descriptor(通过Descriptor的uuid找到对应的Descriptor)

    其次 要知道一些名词:

    1、profile

    profile可以理解为一种规范,一个标准的通信协议,它存在于从机中。蓝牙组织规定了一些标准的profile,例如 HID OVER GATT ,防丢器 ,心率计等。每个profile中会包含多个service,每个service代表从机的一种能力。

    2、service

    service可以理解为一个服务,在ble从机中,通过有多个服务,例如电量信息服务、系统信息服务等,每个service中又包含多个characteristic特征值。每个具体的characteristic特征值才是ble通信的主题。比如当前的电量是80%,所以会通过电量的characteristic特征值存在从机的profile里,这样主机就可以通过这个characteristic来读取80%这个数据

    3、characteristic

    characteristic特征值,ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。

    4、UUID

    UUID,统一识别码,我们刚才提到的service和characteristic,都需要一个唯一的uuid来标识

    UUID的格式:00001101-0000-1000-8000-00805F9B34FB

    整理一下,每个从机都会有一个叫做profile的东西存在,不管是上面的自定义的simpleprofile,还是标准的防丢器profile,他们都是由一些列service组成,然后每个service又包含了多个characteristic,主机和从机之间的通信,均是通过characteristic来实现。

    链接:https://www.jianshu.com/p/3711cfbf7128

    如果拿到一个BLE设备,不知道服务ID,不知道读写的特征值characteristic,可以通过
    List<BluetoothGattService> services = gatt.getServices();来查看所有的服务,和该服务下的特征值.打印出来.


    image.png

    可以通过下载LightBlue(前往iPhone APPstore下载),然后连接BLE设备,就可以查看哪个服务是有关读写服务的,还有其对应的读写特征值是多少.


    434694710209421345.jpg

    BluetoothGattCallback
    //ble蓝牙服务的回调,连接状态改变,发现服务
    private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {

                @Override
                public void onCharacteristicChanged(BluetoothGatt gatt,
                                BluetoothGattCharacteristic characteristic) {
    
                        super.onCharacteristicChanged(gatt, characteristic);
            //收到设备notify值 (设备上报值),根据 characteristic.getUUID()来判断是谁发送值给你,根据characteristic.getValue()来获取这个值
                }
            //如果读取电量(或者读取其他值)成功之后 ,会来到 回调:
                @Override
                public void onCharacteristicRead(BluetoothGatt gatt,
                                BluetoothGattCharacteristic characteristic, int status) {
                        super.onCharacteristicRead(gatt, characteristic, status);
                        //读取到值
                        //收到设备notify值 (设备上报值)
                }
              
            //如果下发配置成功之后,会来到回调:
                @Override
                public void onCharacteristicWrite(BluetoothGatt gatt,
                                BluetoothGattCharacteristic characteristic, int status) {
                        super.onCharacteristicWrite(gatt, characteristic, status);
                                if (status == BluetoothGatt.GATT_SUCCESS) {
                                         //write成功(发送值成功)
                                }
                         
                }
    
                @Override
                public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                int newState) {
                        super.onConnectionStateChange(gatt, status, newState);
                        if (status == BluetoothGatt.GATT_SUCCESS) {
                                if (newState == BluetoothGatt.STATE_CONNECTED) {
                                     // 连接成功
                                 Timber.i("Connected to GATT server.");
                //连接成功之后,我们应该立刻去寻找服务(上面提到的BluetoothGattService),只有寻找到服务之后,才可以和设备进行通信.
                
                        mBluetoothGatt.discoverServices();
                                } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
                                      // 断开连接
                                         
                                }
                        }
                }
    
                @Override
                public void onDescriptorRead(BluetoothGatt gatt,
                                BluetoothGattDescriptor descriptor, int status) {
                        super.onDescriptorRead(gatt, descriptor, status);
                  //标志读取成功
                }
    
                @Override
                public void onDescriptorWrite(BluetoothGatt gatt,
                                BluetoothGattDescriptor descriptor, int status) {
                        super.onDescriptorWrite(gatt, descriptor, status);
    
                }
    
                @Override
                public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
                        super.onReadRemoteRssi(gatt, rssi, status);
                        if (status == BluetoothGatt.GATT_SUCCESS) {
                                  //获取到RSSI,  RSSI 正常情况下 是 一个 负值,如 -33 ; 这个值的绝对值越小,代表设备离手机越近
                                 //通过mBluetoothGatt.readRemoteRssi();来获取
                        }
                }
    
                @Override
                public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
                        super.onReliableWriteCompleted(gatt, status);
                }
    
                @Override
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                        super.onServicesDiscovered(gatt, status);
    
                        if (status == BluetoothGatt.GATT_SUCCESS) {
                                       //寻找到服务
                //根据得到的服务ID,用gatt.getService(uuid)去拿到读写服务
    

    BluetoothGattService serviceRead = gatt.getService(UUID.fromString(GattAttributes.BLE_SPP_SERVICE_READ));
    BluetoothGattService serviceWrite = gatt.getService(UUID.fromString(GattAttributes.BLE_SPP_SERVICE_WRITE));

    if (serviceWrite != null) {
    //找到服务,继续查找特征值,拿到写给设备的特征

    BluetoothGattCharacteristic mWriteCharacteristic = serviceWrite.getCharacteristic(UUID.fromString(GattAttributes.BLE_SPP_WRITE_CHARACTERISTIC));
    }

    //拿到设备主动上报信息的特征
    BluetoothGattCharacteristic mNotifyCharacteristic = serviceRead.getCharacteristic(UUID.fromString(GattAttributes.BLE_SPP_NOTIFY_CHARACTERISTIC));

    if (mNotifyCharacteristic != null) {
    //使能Notify,这句话是设置给BLE设备,让设备能够主动上报信息
    setCharacteristicNotification(mNotifyCharacteristic, true);
    }

    if (bluetoothLeService.mBluetoothGatt != null) {
    //将需要发送的数据byte数组,setValue设置给mWriteCharacteristic
    bluetoothLeService.mWriteCharacteristic.setValue(byte[ ] b);
    //发送数据的方法
    boolean sendSuccess = bluetoothLeService.mBluetoothGatt.writeCharacteristic(bluetoothLeService.mWriteCharacteristic);
    }

                        }
                }
        };
    

    相关文章

      网友评论

          本文标题:Android 蓝牙4.0BLE连接

          本文链接:https://www.haomeiwen.com/subject/cutbdftx.html