This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

how to avoid automatic connection in Android while scanning for devices

Dear all,

I have a project with a nRF51822 based on S110 and SDK10. Almost everything is running fine, but every time I scan for devices, either by calling BluetoothAdapter.startDiscovery() or by doing it manually from Android Bluetooth Settings my Phone connects to the nRF51822.

How can I avoid that? What did I do wrong?

I have tried different values for ble_gap_adv_params_t.type, but I am not able to connect at all if I do not use BLE_GAP_ADV_TYPE_ADV_IND.

Is there an option that I have missed to tell the other peer not to automatically connect, but that allows to connect on demand?

My current peer for testing is a Samsung Galaxy S5 running Android 5.0.2.

The Phone does not automatically connect if I use BluetoothAdapter.startLeScan() (I have not tried BluetoothLeScanner.startScan()), but in Android 6 there is bug and it requires location services to be enabled and that is very hard to explain to the customers. So I would prefer to use BluetoothAdapter.startDiscovery().

UPDATE:

As BluetoothAdapter.startDiscovery() seems to be working fine in Android 6, I will use BluetoothAdapter.startLeScan() on Android 4.x and Android 5.x and BluetoothAdapter.startDiscovery() on Android 6.x and later.

But I still would like to check wether I did something wrong in my nRF51 firmware or if this is a bug in Android 5.x or my Samsung version of Android 5.x?

  • Hello, The BluetoothAdapter.startDiscovery() method is ONLY for standard Bluetooth, not Bluetooth LE. If you want to connect to a BLE device you have to scan using either startLeScan() (for Android 4.3 or 4.4.x), or using BluetoothLeScanner object (for Lollipop and newer). I would recommend using our Compat library: github.com/.../Android-Scanner-Compat-Library. Then you have all the new features also on the old devices and you don't have to do any version checks. It's very easy to use it, follow the steps on the documentation.

    And yes, since Marchmallow you have to ask user for COARSE or FINE LOCATION permission in order to scan. This is not a bug, it's like that by design, as BLE scanning may be used to estimate users location (for example using Beacons located in various places which have a fixed adv packet).

    If you use pairing in your application you don't have to scan at all. Then, you have to instruct your users, that they have to go to Bluetooth Settings, wait until your device will pop up, and click it. Android will connect to it, try to pair and check if it can use it natively (for example HID devices, like keyboards or mice can be used natively, without any 3rd party app). If not, it will disconnect. Then in your app you can request all bonded devices using developer.android.com/.../BluetoothAdapter.html and just connect to it and start using. If your device is does not pair, you have to use scanning, so you have to ask for location permission, just like nRF Master Control Panel or nRF Toolbox apps do.

    Best Regards, Aleksander

    1. BluetoothAdapter.startDiscovery() will find both low energy and classic devices - without the need to enable location services in Android 6.
    2. This does not really answer my question... - My question is: Has the Bluetooth standard a function or something else that I might have missed to automatically connect after a discovery? Or is this a bug in Android?
    3. I have not asked for permissions, yes COARSE or FINE LOCATION permissions are needed (even with startDiscovery()), and yes, Google says that is intended, but since Android 6 you also need to enable location services in addition. Maybe Google would say something else, but I would say it looks like a bug.
  • The BluetoothAdapter.startDiscovery() method will connect to your device, as in standard Bluetooth it usually trying to figure out what service/profiles does a device support. On BLE on the other hand this info is in the adv packet, and connecting is only upon request. This is how I understand it. A connect method may choose a protocol supported by the device, so for BLE devices it will be GATT protocol. The location service is a global switch for all apps to disable location sharing/set available location mode. Instead of disabling Location permission for all (only targeted API23+) apps, user may do it using a tile in notifications panel. If the Location master-switch is disabled it would be hard to understand that some apps can actually get location information.

  • To avoid automatic connection you should use BluetoothAdapter.getBluetoothLeScanner().starScan(...), or the Compat lib that I mentioned before. There is no workaround for scanning without enabling Location Service/permission. I have never tried using startDiscovery().

  • @Aleksander Nowakowski - Thank you for your comments. I have noticed your library, I checked the source code, it is great, good work. I am aware of the location service and permissions problem. - But that does not target my question: Has Bluetooth an automaic-connect-after-discovery-feature (that I might have accidentally activated)?

Related