androidkotlinbluetoothiotscanning

How to discover profiles, used in scanned Bluetooth devices, programmatically through Android app?


I am working on a mobile application, written in Kotlin, which, among other things, retrieves information about nearby Bluetooth devices. One of the requirements is to obtain information about the Bluetooth profiles supported by the scanned device. You can find a complete list of Bluetooth profiles on Wikipedia. The requirement is to scan for each of these profiles.

So far, I have been able to obtain information about the services on a given BLE device:

enter image description here

As far as I know, each profile uses multiple services. I haven't found a way to deduce from such a list what profiles are used. But that may be a dead end.

I also know that the BluetoothProfile class contains constants representing A2DP, GATT, HSP/HFP, HID, HDP and SAP profiles, but I don't know how to implement their detection. I think, this is most promising lead, so I would appreciate any help, regarding


Solution

  • I don't think you can "reliably" determine the profiles of discovered devices until an RFCOMM socket is established (i.e. the peripheral is connected). It looks like you are using the BluetoothLeScanner? This will not find all profiles, for example A2DP. Use the BluetoothAdapter to discover devices. From its results, you will get a BluetoothDevice, on which you can get "rough" data about the class of each device from its bluetoothClass property. From there, you can try to call BluetoothClass.doesClassMatch(Int) which makes educated guesses about profiles, and errs on the side of false positives. This may be good enough for the purposes of your use case, but it isn't 100% reliable until a connection is established:

    BluetoothClass is useful as a hint to roughly describe a device (for example to show an icon in the UI), but does not reliably describe which Bluetooth profiles or services are actually supported by a device. Accurate service discovery is done through SDP requests, which are automatically performed when creating an RFCOMM socket with BluetoothDevice.createRfcommSocketToServiceRecord(UUID) and BluetoothAdapter.listenUsingRfcommWithServiceRecord(String, UUID)

    Use BluetoothDevice#getBluetoothClass to retrieve the class for a remote device.