安卓无法找到蓝牙低功耗设备:onClientRegistered() - status=133 clientIf=0

12

我正在开发一个应用程序,其中我可以找到并配置BLE设备。 我正在使用标准的Android BLE API,但最近遇到了一些奇怪的问题。

当我打开我的应用程序时,BLE扫描正常工作。 我正在使用以下方式进行扫描:

mBluetoothAdapter.startLeScan(mLeScanCallback); // for Kitkat and below

mBluetoothAdapter.getBluetoothLeScanner().startScan(mScanCallback); // for Lollipop and above

在Logcat中,我收到以下消息(我猜这对于这个问题很重要):

D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5

在我的应用程序中,我还可以从我的BLE设备中读取某些特征(例如电池状态)。我连接到一个设备,在单独的片段中使用以下方法读取此特征:

mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mMacAddress);
mBluetoothGatt = mBluetoothDevice.connectGatt(mContext, false, mGattCallback);

特征被正确读取。在onCharacteristicRead回调中,我还会断开连接并关闭Gatt:

mBluetoothGatt.disconnect();
mBluetoothGatt.close();
每次我打开一个片段来读取特征(无论是否为相同的设备),clientIf值都会增加。我可以在LogCat中看到:
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=8
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=9
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=10

一切都运行良好,直到clientIf的值等于10。BLE扫描停止发现任何设备,我无法连接到任何设备以读取任何特征等。而且LogCat无限地显示这些消息:

D/BluetoothGatt: unregisterApp() - mClientIf=0
D/BluetoothGatt: onClientRegistered() - status=133 clientIf=0

唯一的解决方法是关闭应用程序并重新启动它,或通过手动关闭和打开蓝牙来重启。我只在某些设备上遇到过这个问题,比如Xperia Z1(Android KitKat)和Galaxy S4(Android Lollipop)。我无法在运行Android Marshmallow的Xperia Z3 Compact上重现此问题...

有什么我可以做的吗?我已经尝试了多种“解决方案”,例如-从UI线程调用所有BLE方法和关闭/断开GATT,但都没有帮助。我该怎么办才能解决这个问题?

2个回答

13

我将回答自己的问题,因为这可能会帮助有相同问题的人。

首先,我无法解决蓝牙在 mClientIf 值达到 10 后崩溃的问题。但是我找到了一个解决方法,可以帮助我的情况。

尽管我在第一个 Fragment 中停止了信标搜索,并在另一个 Fragment 中开始了特征读取,但 BLE API 显然没有立即停止搜索,在打开下一个 Fragment 后系统会创建另一个“客户端”。

这就是为什么我需要在离开第一个 Fragment 并在另一个中开始读取特征之前等待一段时间的原因。

该方法在“新”FragmentonCreateView 中调用(使用 postDelayed 帮助我解决了问题):

private void getBatteryCharacteristic() {
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                mBeaconBatteryStateReader = new BeaconBatteryStateReader(
                        BeaconDetailsActivity.this,
                        mBeacon.getMacAddress());
                mBeaconBatteryStateReader.readBatteryState(BeaconDetailsActivity.this);
            }
        }, 100);
    }

1
我也遇到了类似的问题,对我来说,在断开连接和扫描之间添加一点延迟也解决了问题。谢谢! - Tijn
我发现了和你一样的解决方案。详情请见:https://github.com/googlesamples/android-BluetoothLeGatt/issues/44 - Sam Protsenko

0
关闭Gatt对象是释放资源的正确方法。如果仍然无法正常工作,则该特定手机上存在Android中的错误。
为了最小化达到限制的机会,您可以确保每个设备永远不会有多个Gatt对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接