title: How does Android detect/determine Bluetooth device type?
body: <h2>Questions first...</h2>
  
  <p>1) How does Android (pre API23) detect device type of Bluetooth devices? Apparently setting the BLE ADV flag <strong>BREDR_NOT_SUPPORTED</strong> 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...</p>
  
  <p>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 <strong>DUAL</strong>. 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...</p>
  
  <h2>... and then perhaps some background/context ;)</h2>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>Everything works like a charm on iOS.</p>
  
  <p>But...</p>
  
  <p>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.</p>
  
  <p>For instance, a few years ago when <strong>API21</strong> was the latest thing I had to explicitly set the  <strong>BREDR_NOT_SUPPORTED</strong> flag AND use reflection to enforce transport = BLE to eventually succeed with my <code>connectGatt(..)</code> request. </p>
  
  <p>But, since <strong>API23</strong> 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... </p>
  
  <p>Instead, the recommendation is to use the <strong>LE_BR_EDR_CONTROLLER</strong> and <strong>LE_BR_EDR_HOST</strong> BLE ADV flags to let Android know that this is indeed a fully capable dual-mode device... </p>
  
  <p>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 <code>DEVICE_TYPE_CLASSIC</code>.</p>