The core value of this group is to bring developers up to speed with BB technology, concentrating on BB10.Exploring efficiency, beauty and power BlackBerry provides to its users by designing Apps that can be used globally and that improves developers life as it improves community life.
Image: “Neuron” courtesy of “dream designed” / FreeDigitalPhotos.net
This article arose out of a real-life project I (@jcmrim) had been working on which involved connecting medical devices to BlackBerry 10 handsets using Bluetooth Serial Port Profile (SPP). What made it particularly interesting is that the BlackBerry 10 application was a WebWorks / Cordova application.
This model was very successful, so obviously I wanted to share this with the developer community. However, the plugin itself was matched closely to the medical devices it needed to communicate with, and it was unlikely that the ordinary developer would have access to a blood pressure and oximeter monitoring device. So I crafted a simpler version of the plugin that was device-agnostic, that would simply send and receive data over an SPP connection.
Using this as a base, and inspired by an existing Cascades application on GitHub, I wrote a simple WebWorks “chat” application that used the plugin to communicate, using Bluetooth SPP, between two BlackBerry 10 devices to demonstrate the basic architecture and model of the application and plugin. If you have another Bluetooth use-case, it should be easy to follow this pattern to develop your application.
Before delving into the plugin itself, let’s just look at how the “chat” application behaves.
The “Chat” Application and How It Behaves
I recorded a short video that demonstrates the main elements of this simple application:
Listening for an inbound Bluetooth connection
Scanning for nearby devices
Connecting to a selected Bluetooth device
Bi-directional exchange of simple messages
Disconnection of the two devices
OK, I’m not by any means an expert at designing user interfaces, particularly HTML5 ones, so forgive me if it seems a little Spartan. It is, however, completely functional.
Let me just summarize what you’ve just seen: Two BlackBerry 10 devices running a simple WebWorks application are able to establish a Bluetooth SPP connection between themselves and exchange simple messages over this connection. It’s Bluetooth “chat.”
Both the sample “chat” application and the plugin are available as a project on GitHub here:
There are three types of elements in the API:
I use these to set and get values that should be persisted in the plugin. The best example of this is the Bluetooth Address of the device to which to connect. You’d use it like this:
I use this form when some operation, such as sending a message, needs to be performed. I’ll know whether this has been successful by the returned value from the call.
So, the returned value from “sendMessage” would be one of these:
The first thing I want to note is that all return values are of this general pattern: JSON format with common interpretation of attributes such as “status” and “desc”! I’ve chosen to use JSON preferentially since it’s easy to parse both in WebWorks and the plugin itself using the “Json::FastWriter” class and its relatives.
I use this type of function when some operation needs to be initiated. I’ll be able to tell whether the operation has been successfully started by the return value from the call to the function; and, as the operation itself is completed, I’ll receive information back from the plugin using a callback. A good example of this pattern would be the call “listenForConnection()” that starts the plugin listening for inbound connection events. I’d use it something like this:
I can test the variable “foo” to check that the listen request has been initiated correctly and then when an inbound connection is detected by the plugin, the callback “inboundConnectionCallback()” is called by the plugin. The data that is passed back as an argument to the callback function might look something like this:
I can check this and figure out that I’m now connected to a device at the address: “34:BB:1F:3E:77:BC”. Also notice that I supply a description field “desc” in all status messages that you can use in any error messages you need to provide.
There’s just one other point I’d like to note before moving on, and that’s got to do with what actual data the “chat” application will pass to the plugin when it issues a “sendMessage()” request to send data to the other device.
I took the view that I wanted to be able to send arbitrary byte streams across the underlying SPP connection to the peer device and conversely receive arbitrary byte streams. The reason might be that I’d want to use this API to communicate with a device that “speaks” a protocol that is byte-oriented rather than character-oriented. Most medical devices that use SPP communicate like this.
So, the plugin will accept messages of the following format:
And this will be sent over the SPP connection as the byte stream: 02,74,02,05,05,03. This isn’t a random stream of bytes, by the way, but is in fact a request to a particular type of medical device to report its serial number. The 0x02 is “STX” and the 0x03 is “ETX”, which, if any of you remember your basic serial communications, are mnemonics for framing symbols around a message. The reason for this is that many medical devices were designed to work with real serial cable connections to monitoring equipment, and with the advent of Bluetooth the same protocol is simple transported over SPP. This is the reason for the word “Serial” in Serial Port Protocol.
Conversely, data returned from the remote device might be encoded the same way, something like:
So, I can use this to send, unambiguously, the text of messages entered into the input field on the “chat” application. The text of the message entered in this way will be in UTF-16 format; so, for example, string “hello” in the images at the start of this article would actually be passed to the plugin as:
If you’re interested, here’s how I did this in the code of the “chat” application itself:
Using an “ArrayBuffer()” mapped with two views “Uint16Array()” and “Uint8Array()”, I could encode an arbitrary string encoded as UTF-16 unambiguously as a byte array before sending it to the plugin as a JSON string.
Now let’s look in more detail at the plugin itself.
The Plugin Itself
In a sense, I’ve cheated – I have to admit that I didn’t write this plugin from scratch myself. I had help. What I did was to use the excellent Cordova Plugin Template for BlackBerry 10 that you can find on GitHub here:
It comes with an Ant script that you can use to customize various aspects of your plugin, including its name. What you get, after you’ve done this, is a project that you can import into Momentics and a matching sample WebWorks/Cordova application that you can build. You should take a look at this in GitHub since it comes with a great explanation of how a plugin is architected and organized.
I’m going to assume that you’ve done this and now have a grasp of how a plugin works. What I’m going to explain now is how I’ve overlaid this model on top of the BlackBerry 10 Bluetooth SPP APIs.
It’s probably sufficient to look at how one single operation is implemented since the others follow the same pattern. I’ll look at “startDeviceScan()” operation, which looks like this:
I’ll get some immediate status as to the initialization of the scan operation in the variable “foo,” and subsequently, the “data” argument of the callback function will contain the result of the scan.
Much of this is boilerplate code, setting up the “success” and “fail” callbacks, and the plumbing to handle the synchronous and asynchronous aspects of the function call. The “exec()” call makes a call to the next level of the “glue” layer, which is shown in the image below.
The actual call into native code is made in the fragment above – again, pretty much boilerplate code, where a “PluginResult()” object is obtained and a reference to it is saved for later when the asynchronous operation returns. The actual call to native code is made using the object returned from “simpleBtSppPlugin.getInstance()”.
Once you drop into native code, you have to call the appropriate method based on the name of the function you’re calling represented as a character string – something like what is shown in the image below, which calls the appropriate method on an instance of a class the template has provided for us.
In essence, this method is quite simple – all it does is start a pthread() that will perform the actual scan, since it can be a lengthy operation, and return the appropriate JSON to the caller, indicating whether the operation was initiated correctly or not. In the snippet below, “writer” is an instance of “Json::FastWriter”.
Once the pthread() has started, it scans for Bluetooth devices in the same way I’ve done in many other examples.
The key difference is this call made by the thread when it’s just about to exit:
If everything has worked correctly, the user of the plugin’s API will see a response on the callback they have provided with data similar to this:
You can see that, along with a couple of BlackBerry 10 devices, there are also a couple of Estimote beacons in the vicinity . If no devices are found, the response would be like this:
It’s not an error to find no devices, so the “status” field is “OK,” but the “devices” array attribute is an empty array.
That’s about it!
I’ve released V1.0.0 of the SimpleBtSppPlugin plugin containing the features described in this article, so you can download, review, and reuse the full source code. You can find the URL in the “Resources” section below. I hope this has been interesting and will help set you on your way to developing real-world Bluetooth applications for BlackBerry 10.
Please feel free to contact me on Twitter (@jcmrim) if you need help on anything Bluetooth SPP or Smart-related.
As an Enterprise Solutions Manager, I aid our customers with their Enterprise Mobility Management solution, and a large part of that is mobile applications. While in-house custom solutions are always a rewarding challenge, the developer in me loves seeing independent dev shops creating value for the Enterprise and Professional Consumer markets. That’s why I was pleasantly surprised when a contact of mine introduced me to his new startup: Mona Networks.
Mona’s goal is simple: connect the owners and tenants of a large center or building with the thousands of surrounding working professionals that are impacted by its operations on a regular basis. Using their platform, the owner of a property can provide real-time information to users that frequent the area, and allow tenants of the space to post promotional material.
For example, assume you are a professional who works in downtown Toronto next to a major shopping center. You eat at this center frequently; you shop there for a variety of items; you attend events there whenever you’re aware of them; and the list goes on. This center is a staple in your 9-5 life. But how do you know what is actually going on in that center at any given point in time?
This is where Mona comes in. With a unique application for the center you frequent most, you can always stay up-to-speed with events, promotions, and any other relevant news.
When your favorite restaurants and retail stores have specials, you’ll be the first to know. When an impromptu event pops up, you’ll know in time to catch it. Power outage in the building? No problem; the landlord will push a notification out to you so you don’t waste time planning to visit that day.
Mona’s target user demographic is the working professional – a strong overlap with BlackBerry’s core user base. As such, Kofi, Mona’s founder and Chief Product Officer, reached out to me to ensure the Mona user experience was spot on for BlackBerry 10. I met with both himself and Clint, Mona’s CTO, at their office in Toronto to test their product on the all-new BlackBerry Passport, and they were pleasantly surprised; it ran flawlessly!
The ease of BlackBerry’s WebWorks toolset, the incredible hardware built into the BlackBerry Passport, and the power of the BlackBerry 10 mobile OS allow the folks at Mona to provide a seamless experience to their soon-to-be users.
Mona is launching in a big way, with their first customer being the Bay-Adelaide Center. Thousands of people are impacted by this location on a daily basis, which makes it the perfect candidate for Mona’s awesome platform to start with. They will be having their official co-launch party at the Bay-Adelaide Center on Thursday, October 23rd. I highly suggest you check them out if you’re in the area.
I’m excited for Mona’s future, as they are targeting the types of users I have been begging developers to reach for a long time: business professionals and enterprises. There is a tremendous amount of opportunity in this space; Mona is beginning to capitalize on it, and I hope many more follow.
It was only a few years ago when mobile devices were seen as a hindrance and distraction that would lead to decreased productivity. Times have clearly changed and we’ve got the numbers to prove it.
Today, BlackBerry launched the initial results of a global study on productivity. The study, produced in partnership with research firm GfK, revealed that the definition of productivity is changing.
Gone are the days where the concept of productivity was rooted in an employer-imposed 9 to 5 work day. We found that today’s professionals now see productivity as a personal priority rather than something that companies seek for their employees. For instance, 67 percent of business smartphone users are “always looking to improve their productivity” and 69 percent are “constantly looking for new ways to get things done as efficiently as possible.”
Business users are also looking to advance their career while balancing their personal…