Working with Bluetooth Low Energy across Android and iOS
Published on: 23rd May 2019
Often the final release apps that accompany the products we deliver will not be created until a significant time into the development cycle, so we usually create internal apps to help us develop communications protocols and test our prototype software. These internal apps often double up as demonstration tools for our clients because without them it can be difficult to show what the product can do.
The first question when creating an app is usually “Android or iOS?” and from recent experience with Bluetooth-connected product design, we conclude that the answer is, unfortunately, both. Although the latest versions of Android and iOS support the same version of Bluetooth Low Energy, their implementations are slightly different. It is vital that the connected product is compatible with both of these implementations and their quirks from the beginning to avoid untimely surprises. Here we discuss some of the differences between Android and iOS in the context of Bluetooth Low Energy (also known as Bluetooth Smart).
An introduction to Bluetooth pairing
Pairing is the process of associating two Bluetooth devices such that an encrypted connection can be established between them. This consists of generating and distributing secret keys, used to prevent unintended recipients from eavesdropping or even controlling the connection. Usually, the pairing process can be initiated via the phone’s settings app: the user selects the recognisable name in the list and the process begins. The reader will likely have experienced this with their Bluetooth headphones, hands-free kits or portable speakers.
A device holding data that can be requested is able to mandate that the connection is encrypted before sending that data. This means that a request for the encrypted data will be rejected if the connection is not encrypted, i.e. the devices are not paired. When iOS and Android devices receive this type of rejection, the operating system automatically sends a pairing request to initiate pairing.
Differences in pairing between iOS and Android
The iOS settings app does not currently display devices that support only the Low Energy variant of Bluetooth so in order to pair with such a device the user must download that device’s supporting app, which performs the process itself. This means particular attention must be paid to developing the user experience around pairing with the product to ensure compatibility across the two platforms.
Both iOS and Android support pairing outside of the settings app as explained above, but Android offers an ability to initiate pairing programmatically that iOS does not. To initiate pairing with iOS, the app must request some encrypted data. This means that if there is no data mandating encryption the pairing process cannot be initiated. In addition, Android allows the developer to easily determine whether the pairing process has succeeded, whereas in iOS a second request for the encrypted data must be sent to see if it is rejected. In Android it would be possible to work on the user experience around pairing without having implemented any encryption requirements whereas in iOS the encryption requirements would have to be implemented first. This requires some detailed planning around the order in which features are developed.
During the pairing process itself, iOS displays a pop-up asking the user to confirm they wish to pair with the particular device. If the user does not click “Pair” within 30s then the pairing process will not succeed. Android has no such user interaction so the pairing process will complete much faster. This requires careful consideration of any connection timeout implemented by the connected product – if Apple expects a user to take up to 30s to respond to the pop-up, the connection timeout should almost certainly be longer than this.
When it comes to un-pairing or “forgetting” a device, Android allows this to be done programmatically whereas in iOS the user must navigate to the settings app and do it manually. In a development environment, it is common to be pairing with many different devices, so some consideration must be given to how the user might manage the number of devices and whether or not “forgetting” devices is required.
Android also offers some advantages when it comes to identifying devices. Unlike iOS, Android makes it possible to retrieve a list of devices that are already paired with the phone. Android also provides the unique identifier (MAC address) for each device. The combination of these features allows the devices to be identified and selected from a list to initiate an encrypted connection without having to perform the pairing process again. In iOS it is necessary to consider how the devices can be identified and how devices that have previously been paired might be handled.
Android isn’t perfect
It is likely that some readers will conclude, given the points above, that Android is the best platform to develop on – it offers more functionality, simplifies the user interactions and offers easy identification of devices. However, if the product has been developed using Android without taking into consideration the points identified above, it is likely that some aspect of the implementation will not be compatible with iOS or with user expectations. In fact, it might be concluded that development work should be carried out on an iOS platform because the user experience around these missing/complicated features needs to be designed for this case, whereas Android will accommodate them automatically.
In addition, the Android implementation has several issues around the termination of Bluetooth connections that can make it appear as though the connected product is not working correctly. Usually, if a device wishes to terminate a Bluetooth connection it sends a specific terminate message, which the other end acknowledges, and so both devices “agree” to terminate. However, we have repeatedly observed occasions where the Android device does not acknowledge this message, so the connected product attempting to terminate is left waiting not knowing if the connection is terminated or not. In applications where the termination of the connection is the trigger for the product to go to sleep, this can have a significant impact on battery life.
In the scenario where two connected devices move out of range of one another, no terminate message can be received because it simply can’t reach the other end. Bluetooth has a method for identifying when this has happened, called the supervision timeout. This is typically a short timeout where if no messages have been received in this time, the connection is considered terminated. This is great for low-energy applications because it means we don’t waste power waiting for messages from a device that isn’t responding. However, older versions of Android have this supervision timeout set to twenty seconds, which means it takes twenty seconds for the phone to notice that the connection has terminated. Depending on how the app has been implemented, this could make it look like the connected product is still in range but is not sending any data. This can be extremely confusing for users and although in Android 8+ this supervision timeout has been reduced to five seconds, it can have a big impact on the design of the app.
A further peculiarity discovered with the Android implementation of Bluetooth is that when the command to terminate the connection is called, there is a two-second delay before the terminate message is sent. This means the Bluetooth connection is kept alive for two seconds longer than necessary, which for ultra-low power applications can have a significant impact on battery life. There is an associated problem whereby if the app attempts to connect to the product again before the two seconds delay has elapsed, the terminate message is never sent at all. For applications where the termination of the connection is the trigger for the connected product to go to sleep, this can result in unexpected behaviour.
The reader might now conclude that if Android has so many problems with connection termination, iOS makes the best platform to develop on because no time needs to be spent discovering and addressing these and other related issues. However, the counter-argument says that if the app were developed solely on iOS, the product could be missing vital mitigations for these issues and could result in excess power consumption leading to reduced battery life.
From our extensive experience of the issues discussed above, we have identified some important considerations both for the development of a high-quality product and for the reality of a development environment:
- What do we want the user experience around pairing to look like? Do we want the user to be able to pair via the settings app or do we want them to have a specific app?
- If we need to support the pairing process, which data will mandate encryption? Do we need to work on the user experience first or the encryption requirements first? How long should the connection be kept alive?
- How do we identify prototype products during development if we can’t use the MAC address? Will this approach be the same in production or will we require an alternative method?
- What should the connected product do if it doesn’t receive an acknowledgement to its terminate message?
- How can the app be designed to mitigate the delay introduced by the supervision timeout? Can we report this to the user? Can we make sure this isn’t interpreted as the product not working?
- How can we design the user interface of the app to ensure we don’t try to connect to a device until the two-second delay has elapsed? Will it look like the product isn’t working correctly?
- What other unexpected sequences of events over Bluetooth could impact the behaviour of our connected product? Can we mitigate these potential risks?
Developing a connected product compatible with Android and iOS and their various versions presents more challenges that might immediately be apparent, but through the use of appropriate tools, we can identify the key concerns from an early stage. Working with both Android and iOS will have development timing and budget implications but ignoring the particular requirements of either during the development process is likely to result in an inconsistent user experience and could even negatively affect the behaviour of the connected product itself.
DCA have developed a number of Bluetooth-connected products for our clients; if you would like to talk to us further about our experience in these areas, please contact us.
Article written by Hester Corne, Software Engineer.