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

时间:2015-02-12 01:11:38

标签: android bluetooth-lowenergy

我正在开发一个配置信标的项目。通电后的一段时间内,信标变为不可配置,直到电源循环。为了显示可配置信标的列表,我正在查看某些特征(蓝牙设备名称,广告包中的某些制造商数据)。我还需要知道它是否可连接",i。即如果设备的BLE通告数据包中的PDU类型指示它是可连接的。我已经在Android 4.X和5.X中搜索了高低的Android蓝牙类,并且找不到能告诉我这些信息的任何内容。

我意识到确定信标可连接性的一种方法是连接到它,例如。 g。:device.connectGatt(...)。但是,在onConnectionStateChange回调STATE_DISCONNECTED之前,我有时会看到它花费超过两分钟。此外,在一个环境中可能有许多这样的信标,并且连接到可能可配置的每个信标都是低效的。

可以在advertisementData回调方法CBAdvertisementDataIsConnectable中的密钥CBCentralManagerDelegate下的centralManager:didDiscoverPeripheral:advertisementData:RSSI字典中找到此属性的iOS等价物。

所以,问题是:在Android上是否有办法确定BLE设备是否可连接"从广告数据或扫描结果或......?

2 个答案:

答案 0 :(得分:7)

更新:根据Android O SDK中的最终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.x的回调中得到了三个字段:

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

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

在Android 8.0之前,似乎这些信息不会从BlueDroid堆栈传递到Java层。

答案 1 :(得分:4)

因为北欧的nRF主控制面板可以做到这一点。

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

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

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

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