Android 蓝牙4.0BLE连接

2018-05-17  本文已影响0人  Ayugone

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);
}

                    }
            }
    };
上一篇下一篇

猜你喜欢

热点阅读