BLE4.0-->Bluetooth low energy

蓝牙4.0是 蓝牙3.0+HS规范的补充,专门面向对成本和功耗都有较高要求的无线方案,可广泛用于卫生保健、 体育健身、家庭娱乐、安全保障等诸多领域。
它支持两种部署方式:双模式和单模式。双模式中,低功耗 蓝牙功能 集成在现有的经典蓝牙控制器中,或再在现有经典蓝牙技术(2.1+EDR/3.0+HS)芯片上增加低功耗堆栈,整体架构基本不变,因此成本增加有限。 单模式面向 高度 集成、 紧凑 的设备,使用一个轻量级连接层(Link Layer)提供超低功耗的待机模式操作、简单设备恢复和可靠的点对多点数据传输,还能让联网传感器在蓝牙传输中安排好低功耗蓝牙流量的次序,同时还有高级节能和安全加密连接。
优点: 低功耗、低成本、开放性(2.4GHz的频段全球开发),适应时代潮流
技术细节:
速度:支持1Mbps数据传输率下的超短数据包,最少8个八组位,最多27个。所有连接都使用 蓝牙2.1加入的减速呼吸模式(sniff subrating)来达到超低工作循环。
跳频:使用所有蓝牙规范版本通用的自适应跳频,最大程度地减少和其他2.4GHz ISM频段无线技术的串扰。
主控制:更加智能,可以休眠更长时间,只在需要执行动作的时候才唤醒。
延迟:最短可在3毫秒内完成连接设置并开始传输数据。
范围:提高调制指数,最大范围可超过100米(根据不同应用领域, 距离不同)。
健壮性:所有数据包都使用24-bit CRC校验,确保最大程度抵御干扰。
安全:使用AES-128 CCM加密算法进行数据包加密和认证。
拓扑:每个数据包的每次接收都使用32位寻址,理论上可连接数十亿设备;针对一对一连接优化,并支持星形拓扑的一对多连接;使用快速连接和断开,数据可以再网状拓扑内转移而无需维持复杂的 网状网络。
应用: 健康医疗、智能家居、物品防丢、蓝牙立体声耳机、蓝牙免提电话、蓝牙音响、HID人机交换、蓝牙游戏手柄、蓝牙3D眼镜
传统蓝牙-技术相关:
1、打开蓝牙:BluetoothAdapter.getDefaultAdapter().enable();
或:
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
2、关闭蓝牙:BluetoothAdapter.getDefaultAdapter().disable();
3、开始扫描外围设备:BluetoothAdapter.getDefaultAdapter().startDiscovery();
停止扫描:BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
4、获取已经配对的设备数组:BluetoothAdapter.getDefaultAdapter().getBondedDevices();
5、蓝牙通信:
服务端:
String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
UUID uuid = UUID.fromString(SPP_UUID);
BluetoothServerSocket serverSocket = null;
serverSocket =BluetoothAdapter.getDefaultAdapter() .listenUsingRfcommWithServiceRecord("now", uuid);
客户端:
String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
UUID uuid = UUID.fromString(SPP_UUID);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(MainActivity.MAC);
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid);
BLE4.0-技术相关:
1、得到BluetoothAdapter对象:
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
2、开始扫描外围设备:
mBluetoothAdapter . startLeScan (BluetoothAdapter. LeScanCallback );在回调中得到BluetoothDevice device ;
附:若知道设备的mac可通过mBluetoothAdapter. getRemoteDevice (mac)得到设备的BluetoothDevice device ;
停止扫描:mBluetoothAdapter. stopLeScan ( BluetoothAdapter.LeScanCallback );
3、连接设备:device.connectGatt(Context,boolean,BluetoothGattCallback);得到
Blue toothGattgatt对象,可以与设备通信
4、通过修改gatt里Service、Characteristic、Descriptor的值,并结合
BluetoothGattCallback的回调方法与设备通信;
一个设备可以有多个Service,一个Service可以有多个Characteristic,一个Characteristic可以
有一个Value和多个Descriptor, 一个Descriptor有一个Value。
具体: BluetoothGattService service = gatt.getService(UUID);
BluetoothGattCharacteristic characteristic = service. getCharacteristic (UUID);
BluetoothGattDescriptor descriptor = characteristic. getDescriptor (UUID);
descriptor. setValue (byte[] byte);
gatt. writeDescriptor (descriptor);
gatt. writeCharacteristic (characteristic);
BluetoothGattCallback的回调方法:
gatt.setCharacteristicNotification(characteristic, true) ------> BluetoothGattCallback.onCharacteristicChanged
gatt.readCharacteristic(characteristic) ------------------------> BluetoothGattCallback.onCharacteristicRead
gatt.writeCharacteristic(mCurrentcharacteristic) ------------> BluetoothGattCallback.onCharacteristicWrite
连接蓝牙或者断开蓝牙 --------------------------------------------> BluetoothGattCallback.onConnectionStateChange
gatt.readDescriptor(descriptor) ---------------------------------> BluetoothGattCallback.onDescriptorRead
gatt.writeDescriptor(descriptor) ---------------------------------> BluetoothGattCallback.onDescriptorWrite
gatt.readRemoteRssi() -------------------------------------------> BluetoothGattCallback.onReadRemoteRssi
gatt.executeReliableWrite() --------------------------------------> BluetoothGattCallback.onReliableWriteCompleted
gatt.discoverServices() -------------------------------------------> BluetoothGattCallback.onServicesDiscovered
经验:
1、 通过使用if(gatt==null)来判断gatt是否被创建过,如果创建过就使用gatt.connect();重新建立连接。
但是在这种情况下测试的结果是重新连接需要花费很长的时间。
 解决办法是通过gatt = device.connectGatt(this, false, gattCallback);建立一个新的连接对象,很明显这样的速度要比上一种方法快很多
然而,多次创建gatt连接对象的直接结果是创建过6个以上gatt后就会再也连接不上任何设备,原因应该是android中对BLE限制了同时连接的数量为6个
 解决办法是在每一次重新连接时都执行一次gatt.close();关闭上一个连接。
有人说为什么不在gatt.disconnect();后加一条gatt.close();呢,原因是如果立即执行gatt.close();会导致gattCallback无法收到STATE_DISCONNECTED的状态。
当然,最好的办法是在gattCallback收到STATE_DISCONNECTED后再执行gatt.close();,这样逻辑上会更清析一些。
2、这样的解决方法(在每次connect前,检查是否已经有了Gatt对象,有了的话,就close,然后建立连接重新分配-这个方法)是没错的。真实的原因是每一次连接都会生成一个Gatt对象,每一个Gatt对象都需要断开连接,不然的话,一旦其中有一个Gatt对象没有断开连接,系统就会认为你是在连接的,让你连扫描都扫描不到这个设备,就别说继续连接了。。。。你的方法是正好保证了系统中只有一个Gatt对象,且把真实的(也就是最后的那个)给保存了起来,用于实际操作。而disconnect本身在这个算法里面就可以代替close。close和disconnect的区别在于,close除了断开连接外,还会释放掉所有资源,导致不可以直接在后面的操作中用gatt对象的connect直接连接,而disconnect并不释放资源,所以,所有的资源还保存着,就可以用Gatt的connect进行简单恢复连接,而不是在device那一层进行操作。至于为啥允许可以对一个外设连接多次,这个事情我也很纳闷,不知道什么场景需要这样的操作。。。

你可能感兴趣的:(BLE4.0-->Bluetooth low energy)