一、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()之后),以下的写操作是无效的。

解决办法推荐:将所有的写或者读操作写到一个队列里,封装成一个同步的操作,在操作没有返回之前,让下一个操作等待。