Jolla and SailfishOS
Bluetooth Discovery
Project code is up on Github.
The time has come to get more serious about some software development for the Jolla phone.
Since I have been playing around with all the Cypress PSoC BLE stuff lately, let's see what the Jolla has to offer.
To make it short:
- There is no "out of the box" Blutooth Low Energy (BLE) support
- Not in the SailfishOS
- Not in any API I could find
- Bluetooth (BR ? / EDR ?) aka Bluetooth classic is supported
- by the SailfishOS
- by the Qt5 libraries
Bluetooth in Qt5 on Jolla
Ok, the goal here is not to write a full featured application that uses Bluetooth for something meaningful, but to write a most simple programm that proves the concept on how to access the Bluetooth stack.
While there is a QML type BluetoothDiscoveryModel
I did not like it, when I tried to use it.
It seems to me, that working directly with the QBluetooth...
C++ classes from the Qt libraries to implement the business logic
and than just having an adapter for the views implemented in QML, is the much cleaner approach.
So I fired up my Qt Creator 3.5.0 (Sailfish OS), that is based on Qt 5.0.0 and was build on May 4th 2016.
First "Same procedure as every year."
File | New File or Project ...
SailfishOS | SailfishOS Qt Quick Application
This creates the default template application and configures the project.
Than:
- I got rid of
SecondPage.qml
- And did some refactoring
In the final step of preparation:
- I inherited the a new C++ class
BluetoothDiscovery
fromQObject
- And did register it as a new qmlType in
main()
inBluetoothDiscovery.cpp
Now the project looks like this:
And this is the changed main()
function:
I did not change anything in BluetoothDiscovery.qml
or CoverPage.qml
.
In FirstPage.qml
I deleted all references to SecondPage.qml
and filled some labels with new text..
The more interesting changes though, are:
- line 34 imports our very own
BluetoothAdapter
that is declared inBluetoothAdapter.h
and implemented inBluetoothAdapter.cpp
- lines 78..85 create an object of the
BluetoothAdapter
class- it is named
bluetoothAdapter
- and three anonymous slots (event handler functions) are defined for BluetoothAdapter's signals,
each printing a debug message on the debug console (see Qt Creator's "Application Output")
- it is named
A scan for new devices is initiated by a user command.
- lines 49..53 define an anonymous event handler function for
MenuItem's click
signal, that- logs a status message to the debug console (line 50)
- invokes
bluetoothAdapter
'sscanForNewDevices()
method (line 51)
The BluetoothAdapter
class is declared in src/BluetoothAdapter.h
as a QObject
child.
By registering it as a qmlType in main()
in src/BluetoothDiscovery.cpp
We make it accessable for the QML system.
- line 21 declares a function, that can be called from QML code (see
FirstPage.qml
line 51) - lines 23..26 declare the signals that the
BluetoothAdapter
might emit. - linea 28..29 declare a slot for a signal that the
BluetoothAdapter
is ready to receive.
The implementation is strait forward:
- lines 4..10 the constructor
- creates a new instance of Qt's
QBluetoothDeviceDiscoveryAgent
class (line 6) - assigns
BluetoothAdapter
'saddNewDevice()
slot toQBluetoothDeviceDiscoveryAgent
'sdeviceDiscovered()
signal (line 8) - assigns
BluetoothAdapter
'sfinishedScanning()
slot toQBluetoothDeviceDiscoveryAgent
'sfinished()
signal (line 9)
- creates a new instance of Qt's
- lines 12..16 the de-constructor
- deletes the instance of Qt's
QBluetoothDeviceDiscoveryAgent
class (line 14), we created in the constructor
- deletes the instance of Qt's
- lines 19..22 the slot
addNewDevice()
- converts some information about the discoverd device into a string and emits the
newDeviceDetected()
signal (line 21)
- converts some information about the discoverd device into a string and emits the
- lines 26..29 the slot
finishedScanning()
- emits the
scanFinished()
signal (line 28)
- emits the
- lines 23..37 if
scanForNewDevices()
is invoked (called)discoveryAgen
'sstart()
function is invoked (line 35)
This call is non-blocking, so the next command is executed right away.- emits the
scanStarted()
signal (line 36)
If everything works as expected, something like this is the result you should see:
The QBluetoothDeviceDiscoveryAgent
object has an internal list of devices it already knows.
So it is normal that, if you start the scan again, only devices are reported, that have not been detected in any scan before, since the program was started.
Having the basics in place, how hard can it be to do the more advanced stuff? ;-)