7

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

该程序首先让您选择您希望设备是外围设备还是中央设备。在中心端,程序首先在 Service 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;
                }

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

stopScan();
mGatt = result.getDevice().connectGatt(BLECentral.this, false, m_BLECentralGattCallBack);

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

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

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

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

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

正常连接时,上述过程可在1.7-2.5秒内完成。每个 write-notify 进程之间,大约需要 0.1s

测试过程中发现以下问题:

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

这似乎是 Android BLE 堆栈的一些错误。因此我尝试实现一个看门狗,如果任何过程没有像预期的那样快,看门狗将激活并关闭中央设备的蓝牙并重新打开,从而主动停止等待蓝​​牙的回复堆栈,预计将是一些错误值。蓝牙重新打开后,中央设备将开始扫描外围设备并继续上述测试。

我试图在看门狗激活期间关闭 Gatt,但是在强制关闭 Gatt 之后,连续的 BLE 连接往往会失败。这样看来,错误往往会在每次失败后累积。所以我求助于通过 BluetoothAdapter...disable() 关闭和打开蓝牙设备

关闭蓝牙并重新打开对某些用户来说是相当麻烦的,因为他们可能正在使用其他蓝牙设备。我的问题是:

  1. 我们如何提高上述测试的稳定性(我的代码有什么问题,或者无论如何我可以更好地使用 BLE 堆栈)?

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

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

4

0 回答 0