What to keep in mind when developing your BLE Android app

BLE is native supported on Android from v4.3. It has been continuously improved as Android evolving. It's getting more and more complex with additional features. It's important that a Bluetooth app should work smoothly on all Android versions, from 4.3 to the latest one. One may find it's tricky to keep track of all the issues from earlier Android versions and the changes in BLE APIs of different API levels.

To help you with this, our app developers have provided a note, discussing about most important changes and added features on newer Android version 5 and 6, including some testings we have done on different Android phones regarding BLE performance.

Some interesting topic:

  1. Required permissions for BLE app.

  2. Scanning: different scan mode, report delay, callback type, etc

  3. Connection: autoConnect, connection parameter update, MTU, number packets per connection parameters.

  4. GATT server, advertising, how to set it up.

This document is strongly recommended to whom developing Android apps:


(Updated 05Dec2016)

Question and issue, please post as a separated case and post the link here.

No Data
  • And here's my feedback on the feedback ;)

    "my source in Google says it's still a thing. How do you know it varies between builds? Are you talking about the different public 7.1-betas or something more internal?"

    When I test again I see that it happens on all Nougat devices I have (3: Nexus 5X, Nexus 6, Sony Xperia Z3). I now notice however that the address type used depends on autoConnect. If the white list is used, random address seems always be assumed. But for autoConnect=false, public address is assumed instead. In earlier Androids it was always public address. If Google says it should be public then it's a bug. This is the commit (2016-02-02) that changed this: android.googlesource.com/.../ and android-review.googlesource.com/. See the last else-block, i.e. under "not a known device, i.e. attempt to connect to device never seen before". Now, instead of always choosing public address it seems they do some heuristics assuming random address, but if it is neither a non-resolvable, resolvable or static random address, then it is certainly a public address. The problem is that the bitcheck is written incorrectly to always return false, so random address is always chosen. That was however fixed by android.googlesource.com/.../ but that commit does not seem to be included in the latest nougat releases, so for now the address is always random.

    And the simple answer to the Google employee's question "how could someone have a random address without scanning?" is simply that for example a static random address may definitely be known beforehand.

    "... it most probably mean that it's a public address, despite the fact that public addresses are super rare, as I can imagine"

    Why do you think public addresses are super rare? Just because Nordic's softdevice defaults to a static random address doesn't mean other stacks do the same ;)

    "as far as I remember in a test I made using a BLE sniffer, when I was trying to connect to an advertising HTC One M8 phone form a Nexus with autoConnect=true, there was no Connection Req at all."

    An easier way to inspect such things are to simply check Android's Bluetooth HCI snoop log. There you see all LE Create Connection commands and exactly what scan parameters are being used. Kitkat had terrible default scan parameters for autoConnect btw, like 11.25 ms each second or so.

    ""In chapter 4.5. With Qualcomm Bluetooth chips, that is used in for example Nexus 5X, I've measured 12 packets per connection event." - wow, that's hell of a chip. Almost as good as Nordic's :)"

    Actually, Broadcom's chips (Nexus 5 for example) aren't actually that bad eihter. It is just the fact that by default Android sets both Minimum_CE_Length and Maximum_CE_Length to 0, and then the chip schedules (heuristically) to use max somewhere between 4 and 7 packets per event or so. If Maximum_CE_Length is set to something bigger, those chips manage to send packets during the whole connection event unless it overlaps with another connection. Some guys at Mediatek are working on a pull request changing this: android-review.googlesource.com/

No Data