一、Ble蓝牙操作流程
蓝牙操作流程图
二、权限声明
1.在Android 6.0(targetSdkVersion小于23)之前在权限的获取和操作只需在AndroidManifest文件中声明这两个权限就可以。
注册蓝牙权限
2.在Android 6.0(targetSdkVersion等于或大于23)之后,操作蓝牙需要申请GPS定位权限,而且在权限的获取和操作上有所改动,分为Normal Permissions和Dangerous Permission。凡是Dangerous Permission都需要动态获取权限。
GPS权限获取
三、获取蓝牙权限
1.对于6.0以上系统需要判断版本调用
版本判断和获取权限
2.系统会回调onRequestPermissionsResult的方法,返回请求权限的结果。
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
四、搜索设备
1.BLE设备的搜索调用BluetoothAdapter的startLeScan方法,如下图所示。
方法1
方法2
2.调用扫描方法之后,Android系统会通过LeScanCallback返回扫描的结果。在 onLeScan() 方法中尽量少做耗时的操作,可以把扫描到的设备,扔到另外一个线程中去处理。
搜索设备回调函数
3.搜索设备是耗电的,所以搜索设备需要有时间限制,在搜索到或者超过预定时间之后需要调用stopLeScan(LeSacnCallback callback)方法停止搜索。
五、连接设备
1.通过扫描获取到的BluetoothDevice对象调用connectGatt方法进行连接设备,如果已知BlE设备mac,可以通过BluetoothAdapter的getRemoteDevice(String address)方法获取BluetoothDevice。
创建gatt连接
2. 连接状态是由mGattCallBack的回调方法onConnectionStateChange(BluetoothGatt gatt, int status, int newState)中返回的。�参数解析:
status:返回Gatt的状态(BluetoothGatt.GATT_SUCCESS:成功)
newState:蓝牙连接状态(BluetoothProfile.STATE_CONNECTED 设备已连接, BluetoothProfile.STATE_ DISCONNECTED设备已断开连接 )
3.蓝牙只能同时连接一个外围设备,如果同时发起多个连接,前面连接失败会后面设备连接阻塞。如果需要连接多个设备,建议队列形式连接,如果连接失败,调用disconnect()方法释放连接。
六、发现并获取BluetoothGattService
当设备连接成功之后,调用BluetoothGatt的discoverServices()获取service。执行完成之后将会回调BluetoothGattCallback的方法onServicesDiscovered(BluetoothGatt gatt, int status)。
BluetoothGatt解析
Android BLE蓝牙通信是通过BluetoothGatt 中的service和Characteristic进行通信的。
通过对外设的连结获取BluetoothGatt ,一个外设只能同时被一个中心设备连结,连结之后外设的蓝牙广播就会中断,其他中心设备将无法连结。
1.BluetoothGatt类包含多个service。
2.每个service中包含多个Characteristic。
3.一个Characteristic中包含一个value和多个Descriptor。
七、注册Notification
当BLE设备主动发送数据的时候,需要注册Notification来接收数据,注册Notification之后,设备发送数据会回调BluetoothGattCallback的onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)方法。如何注册如下操作:
注册蓝牙监听
八、BLE写操作
写数据操作,需要调用BluetoothGatt的writeCharacteristic(BluetoothGattCharacteristic characteristic)的方法,需要写的数据通过BluetoothGattCharacteristic的setValue(byte[] value)方法进行设置。
写命令操作
当对蓝牙操作完成之后 要及时关闭连接。关闭蓝牙连接调用 BluetoothGatt的disconnect()方法,调用BluetoothGatt的close()方法来释放连接对象;
BluetoothGatt的操作,如writeCharacteristic、readCharacteristic、writeDescriptor、readDescriptor和readRemoteRssi()都是异步操作。如果同时执行多个writeCharacteristic操作,在第一个操作没有返回的情况下(回调 onCharacteristicWrite()之后),以下的写操作是无效的。
解决办法推荐:将所有的写或者读操作写到一个队列里,封装成一个同步的操作,在操作没有返回之前,让下一个操作等待。