前言
最近在使用蓝牙4.0做单导联心电监测产品时遇到了一个问题。某些机型在蓝牙4.0传递数据的过程中出现丢包(比如最新华为mate10),导致无法展示正确的心电图。后来经过实测,原来是每秒数据量过大(大概975byte/s),但并不是所有的安卓设备都会丢包,这引起了我的注意。赶紧找硬件开发的同事一起分析,最终得出,mate10的蓝牙4.0通讯默认间隙时间较长,通讯频率降低,导致数据丢失。
1、BLE通讯 Connection paramter
Connection paramter有三种状态:
1.BluetoothGatt.CONNECTION_PRIORITY_BALANCED = 0
使用Bluetooth SIG推荐的连接参数, 如果没有请求连接参数更新,这是默认值。
2.BluetoothGatt.CONNECTION_PRIORITY_HIGH = 1
高优先级,低延迟连接。
3.BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER = 2
低功耗,降低数据速率连接参数
随后,就以上模式进行了针对性的资料查找,蓝牙协议分析 给了我很大的帮助。
2、Android设置BLE连接参数
在BluetoothGattCallback抽象类中,处了有我们熟悉的onConnectionStateChange方法:
/**
* Callback indicating when GATT client has connected/disconnected to/from a remote
* GATT server.
*
* @param gatt GATT client
* @param status Status of the connect or disconnect operation.
* {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param newState Returns the new connection state. Can be one of
* {@link BluetoothProfile#STATE_DISCONNECTED} or
* {@link BluetoothProfile#STATE_CONNECTED}
*/
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
}
还有一个当蓝牙连接参数改变的监听onConnectionUpdated
/**
* Callback indicating the connection parameters were updated.
*
* @param gatt GATT client involved
* @param interval Connection interval used on this connection, 1.25ms unit. Valid
* range is from 6 (7.5ms) to 3200 (4000ms).
* @param latency Slave latency for the connection in number of connection events. Valid
* range is from 0 to 499
* @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
* from 10 (0.1s) to 3200 (32s)
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
* successfully
* @hide
*/
public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,
int status) {
}
也就是说,通过此回调函数,我们可以判断出当前BLE工作的状态。
那么,如何去设置呢?
楼主发现目前处了Android O其他的默认为CONNECTION_PRIORITY_HIGH 。由此可以按照正常的步骤来操作:
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.O) {
requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
mConnectionPriorityOperationInProgress = true;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void requestConnectionPriority(int priority){
if (mBluetoothGatt != null) {
boolean requestConnectionPriority = mBluetoothGatt.requestConnectionPriority(priority);
Log.w("wsh"," requestConnectionPriority : "+ requestConnectionPriority);
}
}
核心方法还是使用系统BluetoothGatt的requestConnectionPriority方法。
3、注意点
在蓝牙设备建立连接之后,系统会默认设定一些连接参数,这样就会多次执行onConnectionUpdated回调,我们一定要通过一些同步机制或延时设置的方式来确保设置参数成功。假如我们设置后,系统又设置了一次,就会出现参数被覆盖的情况。
-
liujinlei9109: 华为手机传大量数据遇到了同样问题,请问现在解决了吗?是修改的系统BluetoothGatt的requestConnectionPriority方法吗,谢谢解答(2个月前#1楼)收起回复
-
-
王小_回复 liujinlei9109: 是的,已经解决了。如文章中所示,在蓝牙连接成功的回调中,判断是8.0系统则调用 requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)方法。 这个方法设置成功后会触发public void requestConnectionPriority(int priority)的回调。 这个是需要时间的,不是马上就后回调,不同机型时间不一样。(1个月前)
-
-
原文:https://blog.csdn.net/hello_json/article/details/79541853?utm_source=copy