Questions first...
1) How does Android (pre API23) detect device type of Bluetooth devices? Apparently setting the BLE ADV flag BREDR_NOT_SUPPORTED in the dual-mode Bluetooth headset I’m trying to connect to does the trick, but at the cost of interfering with classic link setup / pairings in more modern APIs. So that’s not really an option...
2) If nothing can be done FW-wise (which would be the best really) in my Bluetooth headset, could you suggest any ideas of HOW I could perhaps override the BluetoothAdapter’s logic for device detection so that I always return device type DUAL. I mean, I don’t need a proper detection in the app since I already use GATT service UUID filtering during LE scanning to find the device in the first place, so I already know that it’s a “compliant device” as long as I can get Android on pre API23 mobiles to behave accordingly...
... and then perhaps some background/context ;)
I’m making apps for iOS and Android that interact with a Bluetooth headset that I also write the FW for. Hence, I have source code control on the behavior on both the headset as well as the apps.
The headset is based on the CSR8670 chipset from Qualcomm, and acts as a dual-mode Bluetooth “smart ready” spec 4.2 gadget which the typical classic profiles (A2DP/AVRCP/HFP) plus my own custom GATT service as a BLE peripheral running a tunneled propriety serial protocol to interface my app(s) on the phone-side.
Everything works like a charm on iOS.
But...
On Android, I’ve seen a gradual change since the launch of API23 and Marshmallow as BLE ADV data and the ADV flags in particular has begun to be used by Android to control classic Bluetooth link establishment/pairing.
For instance, a few years ago when API21 was the latest thing I had to explicitly set the BREDR_NOT_SUPPORTED flag AND use reflection to enforce transport = BLE to eventually succeed with my connectGatt(..)
request.
But, since API23 this is not needed, nor does it honestly make any sense to have there since the headset IS a dual-mode device with BREDR-support...
Instead, the recommendation is to use the LE_BR_EDR_CONTROLLER and LE_BR_EDR_HOST BLE ADV flags to let Android know that this is indeed a fully capable dual-mode device...
And it works. Just fine. As long as you DO NOT try to run your companion app on the Android API21 phone again which now suddenly fails to detect that my headset IS a dual-mode device. Despite my reflection approaches to force a proper connect with proper transport, Android running API21 on my Samsung S5 “active” test phone simply will not establish a GATT connection to my headset, and I strongly think that it’s correlated with the fact that device type is detected as DEVICE_TYPE_CLASSIC
.