BLE Android-不调用onConnectionStateChange

慢下来:

我在尝试连接到外围设备时遇到问题。有时,回调onConnectionStateChange(...)不会在之后调用BluetoothDevice#connectGatt(...)我试图实现的是由用户操作触发的快速和短连接。

这种情况大约每10次发生1次,而无需采取特定的先后措施。它持续约20到30秒,或者直到应用程序被终止并重新打开。我遵循的正常步骤顺序是:

  1. 扫描设备以查找外围设备。
  2. 致电BluetoothDevice#connectGatt(...)如果连接时间超过1秒,则表示连接已“卡住”,因此将无法连接,因此BluetoothDevice#connectGatt(...)再次调用。最多可以尝试5次。
  3. onConnectionStateChange(...)newStateCONNECTED 调用并开始服务发现。
  4. 其余的操作可以顺利进行。
  5. 断开连接后被BluetoothGatt#close()调用。

问题出现在第3点。有时onConnectionStateChange(...)未调用。我注意到,大多数情况下,问题都是由特定的行为引起的。调用后BluetoothDevice#connectGatt(...)onConnectionStateChange(...)将使用newStateCONNECTED 进行调用但随后几乎立即(约40毫秒)使用newStatusDISCONNECTED 再次进行调用由于状态更改的时间很短,我可以推断出该设备甚至没有尝试建立连接,而是将状态更改为DISCONNECTED。该问题在以下情况下结束:

  1. 20-30秒过去了。在这段时间onConnectionStateChange(...)内从不叫。问题结束时,onConnectionStateChange(...)称为应用程序尝试连接的次数。例如,如果BluetoothDevice#connectGatt(...)被调用15次,onConnectionStateChange(...)则被调用15次,newState等于DISCONNECTED。这很好奇,因为在任何这些连接尝试中都从未将状态更改为CONNECTED。
  2. 该应用程序被杀死并再次启动。

SDK18和SDK 21中会发生此错误。

@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
    String deviceName = device.getName();
    if (deviceName == null) return;
    Log.d("BLUETOOTH CONNECTION", "Device found: " + device.getName());
    if (mMode == SCAN_MODE) {
        mListener.deviceFound(device, rssi, scanRecord);
    }
    else {
        mDevices.put(device.hashCode(), device);
        stopScan();
        // Samsung devices with SDK 18 or 19 requires that connectGatt is called in main thread.
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                Log.d("BLUETOOTH CONNECTION", "Executing first device.connectGatt()");
                BluetoothGatt gatt = device.connectGatt(mContext, false, mGattCallback);
                retryIfNecessary(device, gatt);
                mTryingToConnect = true;
            }
        });
    }
}
private void retryIfNecessary(final BluetoothDevice device, final BluetoothGatt gatt) {
    if (isRetryLimitReached()) {
        Log.d("BLUETOOTH CONNECTION", "Try count limit reached");
        finishConnection(gatt);
        mRetryCount = 0;
        mListener.error(TIMEOUT);
        return;
    }
    mRetryCount++;
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.d("BLUETOOTH CONNECTION", "Check if it is frozen.");
            if (isWorking()) {
                Log.d("BLUETOOTH CONNECTION", "Frozen, create new connection.");
                BluetoothGatt gatt = device.connectGatt(mContext, false, mGattCallback);
                retryIfNecessary(device, gatt);
            }
        }
    }, RETRY_INTERVAL_MS);
}
    @Override
    public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
        Log.d("BLUETOOTH CONNECTION", "On connection state changed. Device: "+ gatt.getDevice().getAddress());
        if (!mConnected && BluetoothGatt.STATE_CONNECTED == newState) {
            Log.d("BLUETOOTH CONNECTION", "Connected");
            mTryingToConnect = false;
            mTryingToDiscoverServices = true;
            mConnected = true;
            gatt.discoverServices();
        }
        else if(BluetoothGatt.STATE_DISCONNECTED == newState) {
            Log.d("BLUETOOTH CONNECTION", "Disconnected and closing gatt.");
            mConnected = false;
            gatt.close();
            if (!mConnectionFinished && mRetryCount == 0) {
                finishConnection(gatt);
            }
        }
    }

我认为外围设备无关紧要,因为iOS应用程序始终可以连接而不会出现此问题。

有任何想法吗?提前致谢。

编辑!

这个答案说:

直接连接的间隔为60毫秒,窗口为30毫秒,因此连接完成的速度更快。另外,一次只能有一个直接连接请求挂起,并且30秒后超时。使用状态= 2,状态= 133调用onConnectionStateChange()来指示此超时。

因此,在这30秒钟的间隔中,有一个待处理的连接请求,并在第二个30超时。这不太可能,但是,我可以做些什么来缩短此时间吗?也许我没有看到关于连接失败的解释。谢谢。

编辑02/03/2016

可能会有帮助的新信息。问题开始时onConnectionStateChange(...)(用newState=DISCONNECTED调用newState=CONNECTED〜40ms 后用调用时),状态为62 = 0x03E。这里是状态代码表示GATT_CONN_FAIL_ESTABLISH。当我检测到此状态时,我正在关闭gatt连接,但是问题仍然存在。我也尝试断开连接并关闭。有想法吗?谢谢。

慢下来:

如果有人遇到类似问题,则最终可以通过更换外围设备(arduino)使用的BLE芯片解决问题。在进行此更改之前,我发现一种变通方法是在每次连接后关闭然后再打开BLE。该解决方案并不完美,但是大大提高了连接速率。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章