Android BLE device connection detection

I am working on a project to set up beacons. After a certain time after turning on the power, the beacon becomes non-configurable until it turns on. To show a list of custom beacons, I’m looking at some features (Bluetooth device name, specific manufacturer’s data in the proposal). I also need to know if it is "pluggable", i.e. e. if the PDU type in the BLE proposal for the device indicates that it is connecting. I was looking for high and low level Android Bluetooth classes, both in Android 4.X and 5.X, and could not find anything that would tell me this information.

I understand that one of the ways to determine whether a beacon can be connected is by connecting to it, for example. g .: device.connectGatt(...) . However, I saw that it takes more than two minutes before the onConnectionStateChange returns with STATE_DISCONNECTED . In addition, there may be many of these beacons in the environment, and connecting to each that can be configured will be ineffective.

The ionic equivalent of this attribute can be found in the advertisementData dictionary under the key CBAdvertisementDataIsConnectable in the CBCentralManagerDelegate centralManager:didDiscoverPeripheral:advertisementData:RSSI callback method.

So, the question is, is there a way on Android to determine if a BLE device is “connected” to advertising data or scan results, or ...?

+8
android bluetooth-lowenergy
source share
2 answers

UPDATE:. AS completed APIs in the Android O SDK, the ScanResult class (itself added with Android 5.0) now has the isConnectable() method. Detection of plug-in advertisements is only possible on Android 8.0+. See here for more information: https://developer.android.com/reference/android/bluetooth/le/ScanResult.html#isConnectable ()

Prior to Android 8.0, unfortunately, this is not possible.

Pluggable ads are defined by PDU 0 byte header. You can see this in the example structure below:

 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 

The problem is with devices prior to Anroid 8.0, the Android scanning API does not give you access to these headers. You get exactly three fields in the callback from Android 4.x:

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

The byte of bytes of scan data starts after the header bytes mentioned above. And from what I see in the definition of BluetoothDevice , none of the fields or methods tells you whether this is a pluggable advertisement - the class is just a container for the bluetooth mac address with methods for implementing functions on the bluetooth stack. And there are no methods in IBluetooth.aidl , which is a private interface to the bluetooth glass (and that BluetoothDevice calls its information) that can receive this flag.

It seems that this information is not transferred to the Java level from the BlueDroid package until Android 8.0.

+7
source share

This should be possible, as the Nordic nRF Master Control Panel does.

After some digging, I think I know how to do it. I'm not sure if this is the right way to do this though.

I tried using LE Advertiser and set the device as pluggable. In the Nordic application, the device is set as pluggable, depending on the bytes found in scanResult.getFlags ().

I found that this code works for my devices:

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

All Articles