使Android BLE(蓝牙LE)显得稳定

Ton*_*Siu 6 java connection android bluetooth stability

我正在编写一个程序,在2个支持android外围设备通信的Android设备之间进行以下BLE通信(在本例中为MOTOROLA MOTO E第2代)到一系列:连接 - >通信 - >断开连接,看看他们是否可以做到稳定性好.还讨论了测试中发现的问题.

该程序首先允许您选择是要将设备设置为外围设备还是中心设备.在中央端,程序首先使用服务UUID上的过滤器扫描外围设备:

                ScanSettings.Builder ssb = new ScanSettings.Builder();
                ssb.setReportDelay(0);
                ssb.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
                ScanSettings ss = ssb.build();

                ScanFilter.Builder sfb = new ScanFilter.Builder();
                sfb.setServiceUuid(BLEShared.SERVICE_UUID);

                LinkedList<ScanFilter> lsf = new LinkedList<ScanFilter>();
                lsf.add(sfb.build());

                BluetoothLeScanner leScanner = m_BluetoothAdapter.getBluetoothLeScanner();
                if(leScanner != null)
                {
                    leScanner.startScan(lsf, ss, blePeripheralScanner);
                    isScanning = true;
                    currentState = BLE_CENTRAL_STATE_SCANNING;
                }
Run Code Online (Sandbox Code Playgroud)

然后,当扫描外围设备时,处理程序将从主线程调用以下内容.

stopScan();
mGatt = result.getDevice().connectGatt(BLECentral.this, false, m_BLECentralGattCallBack);
Run Code Online (Sandbox Code Playgroud)

当连接外围设备(由另一个MOTO E操作)时,在onConnectionStageChange()上完成以下操作

        if(newState == BluetoothGatt.STATE_CONNECTED)
        {
                m_Handler.post(new Runnable(){
                public void run()
                {
                    gatt.discoverServices();
                }
            });
        }
Run Code Online (Sandbox Code Playgroud)

发现所有服务后,该程序执行以下操作:

更新描述符以订阅通知写入一些数据并在接收到从中央发送的数据时发送到外围设备,外围设备将通知值更改.收到数据后,来自外设的更改通知将向外设发送数据.写入和通知过程将完成11次.然后集中调用gatt.disconnect()来断开ble连接.

循环上述过程以测试稳定性.

在正常连接期间,上述过程可在1.7-2.5秒内完成.在每个写通知过程之间,大约需要0.1秒

测试期间发现以下问题:

  1. onConnectionStageChange()需要很长时间才能被称为device.connectGatt(),直到最多30秒.如果发生这么长的等待,下一个onConnectionStageChange()很可能是偶然的失败连接.
  2. 在device.connectGatt()之后快速调用onConnectionStageChange()但偶尔会调用newState = STATE_DISCONNECTED
  3. 每次写入命令之间偶尔需要0.5秒.
  4. 在任何阶段,该过程都会停滞或减慢.

这似乎是Android BLE堆栈的一些缺陷.因此,我尝试实施看门狗,如果任何过程没有达到预期的那么快,看门狗将激活并关闭中央设备的蓝牙并再次打开它,从而主动停止等待来自蓝牙的回复堆栈,预计会出现一些错误值.一旦蓝牙再次打开,中央设备将开始扫描外围设备并继续上述测试.

在看门狗激活期间,我试图关闭Gatt,然而在Gatt强行关闭之后,连续的BLE连接往往会失败.因此,似乎每次失败后误差都会累积.所以我通过BluetoothAdapter关闭和打开蓝牙设备...禁用()

关闭蓝牙并重新打开它对于某些用户而言是相当干扰的,因为他们可能正在使用其他蓝牙设备.我的问题是:

  1. 我们如何才能增强上述测试的稳定性(我的代码有什么问题,或者我怎样才能更好地使用BLE堆栈)?

  2. 如果发生故障,是否可以仅重置BLE堆栈或关闭足够的资源而不是完全切换BLE堆栈?

eclipse项目放在下面,如果你有兴趣给它测试或改进项目,请下载并试一试. https://drive.google.com/file/d/0B-w_C5ISF1UHRXUzd1FrUHpyV0k/view?usp=sharing