检测BLE设备是否可以在Android上连接

我正在开发configuration信标的项目。 开机后一段时间,信标变得不可configuration,直到重新启动。 为了显示可configuration信标列表,我正在查看某些特性(蓝牙设备名称,广告数据包中的某些制造商数据)。 我还需要知道它是否“可连接”,即设备的BLE广播数据包中的PDUtypes是否表示可以连接。 我已经在Android 4.X和5.X上search了Android蓝牙类的高低,并且一直无法find任何可以告诉我这些信息的东西。

我意识到,确定信标可连接性的一种方法是连接到它,例如: device.connectGatt(...) 。 不过,在callbackonConnectionStateChange返回STATE_DISCONNECTED之前,我已经看到它有时需要两分多钟。 而且,在一个环境中可能有许多这样的信标,并且连接到可能可configuration的每一个信标都是低效的。

可以在CBCentralManagerDelegatecallback方法centralManager:didDiscoverPeripheral:advertisementData:RSSI的关键字CBAdvertisementDataIsConnectable下的advertisementData字典中find此属性的iOS等效项。

所以,问题是:Android上有没有一种方法可以确定BLE设备是否可以从广告数据或扫描结果或“…”中“连接”?

Solutions Collecting From Web of "检测BLE设备是否可以在Android上连接"

更新:由于Android O SDK中已ScanResult API, ScanResult类(本身自Android 5.0起添加)现在具有isConnectable()方法。 检测可连接的广告只能在Android 8.0以上。 在这里看到更多的信息: https : //developer.android.com/reference/android/bluetooth/le/ScanResult.html#isConnectable()

在Android 8.0之前,不幸的是它是不可能的。

一个可连接的广播是由PDU头字节0决定的。你可以在下面的例子中看到:

 d6 be 89 8e # Access address for advertising data (this is always the same fixed value) 40 # Advertising Channel PDU Header byte 0. Contains: (type = 0), (tx add = 1), (rx add = 0) 24 # Advertising Channel PDU Header byte 1. Contains: (length = total bytes of the advertising payload + 6 bytes for the BLE mac address.) 05 a2 17 6e 3d 71 # Bluetooth Mac 

问题出现在Anroid 8.0之前的设备上,Android扫描API让你无法访问这些头文件。 您从Android 4.xcallback中正好有三个字段:

 onLeScan(BluetoothDevice device, rssi, byte[] scan data) 

扫描数据字节数组上面提到的标题字节之后开始。 从我所看到的BluetoothDevice定义中,没有任何字段或方法告诉你它是否是一个可连接的广告 – 这个类只是一个蓝牙MAC地址的容器,它具有在蓝牙堆栈上执行function的方法。 而IBluetooth.aidl中没有任何方法,它是蓝牙堆栈的私有接口(以及BluetoothDevice调用来获取其信息),可以得到这个标志。

看来这个信息并没有从Android 8.0之前的BlueDroid栈传递到Java层。

这应该是可能的,因为北欧的nRF主控制面板这样做。

经过一番挖掘,我想我知道它是如何做到这一点。 我不知道这是做正确的方法。

我尝试使用LE Advertiser并将设备设置为可连接。 在Nordic应用程序中,根据在scanResult.getFlags()处find的字节,将设备设置为可连接。

我发现这个代码适用于我的设备:

 int flags = scanResult.getScanRecord().getAdvertiseFlags(); if ((flags & 2) == 2) { //connectable }