In Part 1, I explored some of the practical challenges which mobile application developers face, when they want their application to be available on multiple platforms. I contrasted the building of platform-specific, native applications with cross-platform web applications which execute within a web browser.
I went on to introduce the “hybrid mobile application”, which would appear to offer the best of both worlds, allowing the developer to create one set of application source code using HTML, CSS and JavaScript and to generate a distinct native application which contains it, for one or more target platforms. The hybrid mobile approach gives the mobile application developer a way of creating cross-platform applications which can access native platform capabilities in ways which code executing inside a web browser cannot. Furthermore, they can be published in app stores for people to discover and buy them. OK, I’m onboard!
But what about Bluetooth® technology?
Apache Cordova
As discussed in Part 1, there are various hybrid mobile SDKs to choose from out there. I’ve been using Apache Cordova and had some very satisfactory results, so I’ll use it to illustrate the possibilities for the mobile developer wishing to use Bluetooth in cross-platform applications.
Apache Cordova Bluetooth Plugins
Hybrid mobile applications rely on plugin software components to provide APIs which give access to native platform features, of which Bluetooth® would be a good example, from JavaScript.
Apache Cordova is open source and has a busy and productive community, some of whom contribute plugins. There’s a plugin catalogue which is searchable. Try this search URL to get an idea of the Bluetooth® related plugins which exist: https://cordova.apache.org/plugins/?q=bluetooth
Picking a plugin to use can be problematic though. How do you know whether a plugin has the capabilities you need and is of good quality? The answer I’m afraid is simply to do your homework; read the documentation, scrutinizing the APIs in particular and evaluate quality through creating a suitable proof of concept application before diving into your first serious project.
I’ve used three Bluetooth plugins for various lengths of time and purpose, namely the Evothings plugin, Rand Dusing’s Bluetooth plugin and Don Coleman’s Bluetooth central mode plugin. All three seem to do the job well enough but of the three I seem to have settled on Don Coleman’s plugin as the one I turn to for a typical Bluetooth central mode application. I’ll be using code written for this plugin in my examples below.
Creating Apache Cordova Bluetooth Central Mode Apps
Let’s take a look at how the typical parts of a Bluetooth central mode application might be created with Apache Cordova. Those parts are:
- Discover devices (scanning)
- Connect to a selected device
- Discover services, characteristics and descriptors
- Read and write characteristics
- Enable, receive and disable notifications
To keep things simple, I’ll base my code fragments and explanations on a fictitious, custom Bluetooth® profile which has one service containing one characteristic only. The characteristic supports read, write and notify and therefore has a client characteristic configuration descriptor attached to it. The goal here is to give you a sense of what Apache Cordova Bluetooth-related code looks like.
1. Device Discovery
The call to ble.scan will cause Bluetooth® scanning to be performed for 5000ms. Each time a device is discovered, the onDeviceFound callback function is called and passed a JSON object containing details of the device which might look something like this:
You’ll probably apply some selection criteria based on the contents of these JSON objects, which have of course been populated from Bluetooth advertising packets, and present those devices that are selected to the user in the UI.
The function scanFailure is called if there’s an error. This pattern, where one callback function is provided for handling successful outcomes, followed by another for error handling, is very common in Apache Cordova development in general.
2. Connecting to a Device
ble.connect initiates connecting to the device with the address provided as an argument. This is the “id” property from the device JSON object we acquired during the scanning process. Once again, we provide success and failure callback functions as parameters.
As well as connecting to the selected device, this API function automatically performs GATT service discovery when it connects so that item (3) from our list of “application parts” above has already been performed for us. The “peripheral” JSON object which gets passed to our success callback function contains an array of service UUIDs and we can iterate through it to check that the device we just connected to has the GATT services we need.
3. Discover services, characteristics and descriptors
We have no work to do here. Per my last paragraph, the act of connecting to a device was all we needed to trigger service discovery. Nice!
4. Reading and Writing to Characteristics
Reading characteristics couldn’t really be any easier. ble.read needs a device ID, service UUID and characteristic UUID plus a function to pass the read data to and an error handler function.
Data is always provided in the form of a JavaScript ArrayBuffer so it’s the application’s responsibility to convert it to an appropriate data type and format. In the fragment shown here, I’m simply reading the serial number characteristic (UUID 0x2A25) from the device information service (UUID 0x180A) and then converting it to a Unicode string and logging it.
Writing is remarkably similar. Obviously, we also have to provide the data value which we want to write to the characteristic and as you can see from my example, this is also provided as an ArrayBuffer.
5. Enable, receive and disable notifications
ble.startNotification updates the Client Characteristic Configuration Descriptor associated with specified characteristic and service so that notifications are switched on. One again we have that familiar pattern of a callback function for the success case and a second callback function for handling errors. Our success function will be called every time a notification for this characteristic is received and it’s passed the characteristic value in an ArrayBuffer. At this point we need to know what values and data type to expect from the characteristic so that we can properly decode it. I’m simply taking the data to be an array of unsigned 8 bit integers and logging the first byte to the console.
The syntax of the stopNotification function is very similar:
So that’s it. We have a collection of very simple and easy to use JavaScript functions for the most common Bluetooth® operations which your application might need to perform. What I’ve presented here is a small subset of the available functions in the plugin’s API though so I recommend you take a look at the documentation and skim through the full list to get a proper appreciation.
Building for a Target Platform
Coding is only one aspect of using Apache Cordova. You need to know how to create a project, configure the platforms you can build for and the plugins you will be using. You need to know how to build and install on devices. To that end, here’s a sample “session” showing me going through each of those steps and finishing by testing on an Android device plugged into my computer.
Note that you need npm installed and the native SDK for your target platforms such as Xcode for iOS or Android Developer Studio for Android applications. With those prerequisites in place though, it’s a piece of cake. Create a project, add target platforms and plugins to it, code your HTML, CSS and JavaScript and then build and install, all with a few very simple commands from a shell.
Conclusion
The hybrid mobile approach has some pretty compelling advantages over pure web applications and native applications too. There are limitations and compromises you might hit or need to make but few, if any of them, would appear to relate to Bluetooth® technology. Support for Bluetooth via plugin APIs looks excellent, with plugins available for both central mode, featured in this article, and GAP peripherals too.
Web technologies and Bluetooth are everywhere. They could just be the perfect technology pairing!