summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorNedim Hadzic <nhadzic@blackberry.com>2014-01-30 23:04:20 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-21 21:40:30 +0100
commiteea868ab5ffb925eadca66b25ff96cdaae5b0111 (patch)
tree91f09191d51f45dbc148079450b8e91f16316fda /examples
parent97145ded82e657b13dd43ebf9fa4671171eeefd6 (diff)
Heart Listener example added
Bluetooth Low Energy example for connecting and receiving measurements from the heart belt. Documentation added too. [ChangeLog][QtBluetooth] Heart Listener Bluetooth Low Energy heart belt example has been added Change-Id: I1b690827af85411c962eb09aa87936f1fb7d9246 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/bluetooth/bluetooth.pro3
-rw-r--r--examples/bluetooth/heartlistener/assets/Button.qml77
-rw-r--r--examples/bluetooth/heartlistener/assets/Point.qml51
-rw-r--r--examples/bluetooth/heartlistener/assets/blue_heart.pngbin0 -> 7283 bytes
-rw-r--r--examples/bluetooth/heartlistener/assets/blue_heart_small.pngbin0 -> 250 bytes
-rw-r--r--examples/bluetooth/heartlistener/assets/busy_dark.pngbin0 -> 1130 bytes
-rw-r--r--examples/bluetooth/heartlistener/assets/dialog.qml61
-rw-r--r--examples/bluetooth/heartlistener/assets/draw.js74
-rw-r--r--examples/bluetooth/heartlistener/assets/home.qml186
-rw-r--r--examples/bluetooth/heartlistener/assets/main.qml84
-rw-r--r--examples/bluetooth/heartlistener/assets/monitor.qml154
-rw-r--r--examples/bluetooth/heartlistener/assets/results.qml290
-rw-r--r--examples/bluetooth/heartlistener/assets/star.pngbin0 -> 262 bytes
-rw-r--r--examples/bluetooth/heartlistener/deviceinfo.cpp57
-rw-r--r--examples/bluetooth/heartlistener/deviceinfo.h68
-rw-r--r--examples/bluetooth/heartlistener/doc/images/hearratemonitor.pngbin0 -> 46437 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/images/hearrateresults.pngbin0 -> 38983 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/images/hearrateresults1.pngbin0 -> 42472 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/images/heartrateintro.pngbin0 -> 21538 bytes
-rw-r--r--examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc82
-rw-r--r--examples/bluetooth/heartlistener/heartlistener.pro20
-rw-r--r--examples/bluetooth/heartlistener/heartrate.cpp397
-rw-r--r--examples/bluetooth/heartlistener/heartrate.h144
-rw-r--r--examples/bluetooth/heartlistener/main.cpp58
-rw-r--r--examples/bluetooth/heartlistener/resources.qrc16
25 files changed, 1821 insertions, 1 deletions
diff --git a/examples/bluetooth/bluetooth.pro b/examples/bluetooth/bluetooth.pro
index 78ba1fc1..f7fe9d20 100644
--- a/examples/bluetooth/bluetooth.pro
+++ b/examples/bluetooth/bluetooth.pro
@@ -8,4 +8,5 @@ qtHaveModule(widgets) {
qtHaveModule(quick): SUBDIRS += scanner \
picturetransfer \
- lowenergyscanner
+ lowenergyscanner \
+ heartlistener
diff --git a/examples/bluetooth/heartlistener/assets/Button.qml b/examples/bluetooth/heartlistener/assets/Button.qml
new file mode 100644
index 00000000..40e98875
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/Button.qml
@@ -0,0 +1,77 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id:button
+ //color: "#3870BA"
+
+ property real buttonWidth: 300
+ property real buttonHeight: 80
+ property string text: "Button"
+
+ signal buttonClick()
+ width: click.pressed ? (buttonWidth - 15) : buttonWidth
+ height: click.pressed ? (buttonHeight - 15) :buttonHeight
+
+ color: click.pressed ? "#3265A7" : "#3870BA"
+
+ border.color: "#F0EBED"
+ border.width: 5
+ radius: 10
+
+ Text {
+ id: label
+ font.pixelSize: 30; font.bold: true
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ elide: Text.ElideMiddle
+ color: "#F0EBED"
+ text: button.text
+ }
+
+ MouseArea {
+ id: click
+ anchors.fill: parent
+ onClicked: buttonClick()
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/Point.qml b/examples/bluetooth/heartlistener/assets/Point.qml
new file mode 100644
index 00000000..2ed94a4d
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/Point.qml
@@ -0,0 +1,51 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: point
+
+ Image {
+ width: 10; height: 7
+ smooth: true
+ source: "blue_heart_small.png"
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/blue_heart.png b/examples/bluetooth/heartlistener/assets/blue_heart.png
new file mode 100644
index 00000000..997ee699
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/blue_heart.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/assets/blue_heart_small.png b/examples/bluetooth/heartlistener/assets/blue_heart_small.png
new file mode 100644
index 00000000..7bd1f981
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/blue_heart_small.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/assets/busy_dark.png b/examples/bluetooth/heartlistener/assets/busy_dark.png
new file mode 100644
index 00000000..3a105953
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/busy_dark.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/assets/dialog.qml b/examples/bluetooth/heartlistener/assets/dialog.qml
new file mode 100644
index 00000000..45b64cf3
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/dialog.qml
@@ -0,0 +1,61 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ opacity: 0.8
+ color: "#E0DEDF"
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ property int hr: heartRate.hr
+ Text {
+ text: heartRate.message
+ color: "#3870BA"
+
+ }
+
+ onHrChanged: {
+ if (heartRate.hr > 0) {
+ root.destroy()
+ }
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/draw.js b/examples/bluetooth/heartlistener/assets/draw.js
new file mode 100644
index 00000000..a5de5474
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/draw.js
@@ -0,0 +1,74 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+var component;
+var size = 0;
+var counter = 0;
+var difference = 0;
+
+function start() {
+ size = heartRate.measurementsSize();
+ difference = (plot.width-topbar.width)/size;
+ console.log(size +" "+ plot.width);
+ for (var i = 0; i< size; i++) {
+ var value = heartRate.measurements(i);
+
+ drawIt(value);
+ counter++;
+ }
+}
+
+function drawIt(value) {
+ if (component == null)
+ component = Qt.createComponent("Point.qml");
+ if (component.status == Component.Ready) {
+ var dynamicObject = component.createObject(plot);
+ if (dynamicObject == null) {
+ console.log("error creating block");
+ console.log(component.errorString());
+ return false;
+ }
+ dynamicObject.x = 10+(counter*difference);
+ console.log(plot.height)
+ dynamicObject.y = plot.height -value;
+
+ }
+}
+
diff --git a/examples/bluetooth/heartlistener/assets/home.qml b/examples/bluetooth/heartlistener/assets/home.qml
new file mode 100644
index 00000000..2c5e9485
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/home.qml
@@ -0,0 +1,186 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: screen
+ color: "#F0EBED"
+ property string message: heartRate.message
+ onMessageChanged: {
+ if (heartRate.message != "Scanning for devices..." && heartRate.message != "Low Energy device found. Scanning for more...") {
+ background.visible = false;
+ demoMode.visible = true;
+ }
+ else {
+ demoMode.visible = false;
+ background.visible = true;
+ }
+ }
+
+ Rectangle {
+ id:select
+ width: parent.width
+ anchors.top: parent.top
+ height: 80
+ color: "#F0EBED"
+ border.color: "#3870BA"
+ border.width: 2
+ radius: 10
+
+ Text {
+ id: selectText
+ color: "#3870BA"
+ font.pixelSize: 34
+ anchors.centerIn: parent
+ text: "Select Device"
+ }
+ }
+
+ Rectangle {
+ id: spinner
+ width: parent.width
+ anchors.top: select.bottom
+ anchors.bottom: demoMode.top
+ visible: false
+ color: "#F0EBED"
+ z: 100
+
+ Rectangle {
+ id: inside
+ anchors.centerIn: parent
+ Image {
+ id: background
+
+ width:100
+ height:100
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ source: "busy_dark.png"
+ fillMode: Image.PreserveAspectFit
+ NumberAnimation on rotation { duration: 3000; from:0; to: 360; loops: Animation.Infinite}
+ }
+
+ Text {
+ id: infotext
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: background.bottom
+ text: heartRate.message
+ color: "#8F8F8F"
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ heartRate.deviceSearch();
+ spinner.visible=true;
+ }
+
+ ListView {
+ id: theListView
+ width: parent.width
+ onModelChanged: spinner.visible=false
+ anchors.top: select.bottom
+ anchors.bottom: demoMode.top
+ model: heartRate.name
+
+ delegate: Rectangle {
+ id: box
+ height:140
+ width: parent.width
+ color: "#3870BA"
+ border.color: "#F0EBED"
+ border.width: 5
+ radius: 15
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: { box.color= "#3265A7"; box.height=110}
+ onClicked: {
+ heartRate.connectToService(modelData.deviceAddress);
+ pageLoader.source="monitor.qml";
+ }
+ }
+
+ Text {
+ id: device
+ font.pixelSize: 30
+ text: modelData.deviceName
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "#F0EBED"
+ }
+
+ Text {
+ id: deviceAddress
+ font.pixelSize: 30
+ text: modelData.deviceAddress
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "#F0EBED"
+ }
+ }
+ }
+
+ Button {
+ id:demoMode
+ buttonWidth: parent.width
+ buttonHeight: 0.1*parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: scanAgain.top
+ text: "Run Demo"
+ onButtonClick: {
+ heartRate.startDemo();
+ pageLoader.source="monitor.qml";
+ }
+ }
+
+ Button {
+ id:scanAgain
+ buttonWidth: parent.width
+ buttonHeight: 0.1*parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ text: "Menu"
+ onButtonClick: pageLoader.source="main.qml"
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/main.qml b/examples/bluetooth/heartlistener/assets/main.qml
new file mode 100644
index 00000000..e892eb47
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/main.qml
@@ -0,0 +1,84 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 400
+ height: 600
+ id: begin
+
+ Rectangle {
+ color: "#F0EBED"
+ anchors.fill: parent
+ Rectangle {
+ id: about
+ width: 0.75*parent.width
+ height: 0.1*parent.height
+ anchors.top: parent.top
+ anchors.topMargin: 20
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "#F0EBED"
+ border.color: "#3870BA"
+ border.width: 2
+ radius: 10
+ Text {
+ id: aboutinfo
+ anchors.centerIn: parent
+ color: "#3870BA"
+ text: "Welcome to the Heart Listener Application"
+ }
+ }
+
+ Button {
+ id:call
+ buttonWidth: 0.75*parent.width
+ buttonHeight: 0.15*parent.height
+ anchors.centerIn: parent
+ text: "Scan for Devices"
+ onButtonClick: pageLoader.source="home.qml"
+ }
+ }
+
+ Loader {
+ id: pageLoader
+ anchors.fill: parent
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/monitor.qml b/examples/bluetooth/heartlistener/assets/monitor.qml
new file mode 100644
index 00000000..5dbf66c3
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/monitor.qml
@@ -0,0 +1,154 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ id: screenMonitor
+ color: "#F0EBED"
+
+ Button {
+ id:menu
+ buttonWidth: parent.width
+ buttonHeight: 0.1 * parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ text: "Menu"
+ onButtonClick: {
+ heartRate.disconnectService();
+ pageLoader.source="home.qml";
+ }
+ }
+
+ Text {
+ id: hrValue
+ font.pointSize: 24; font.bold: true
+ anchors.top:menu.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 25
+
+ color: "#3870BA"
+ text: heartRate.hr
+ onTextChanged: {
+ if (heartRate.hr > 0 && updatei != null && heartRate.numDevices() > 0) {
+ updatei.destroy()
+ }
+ }
+ }
+
+ Rectangle {
+ id: updatei
+ width: parent.width
+ height: 80
+ anchors.bottom: stop.top
+
+ color: "#F0EBED"
+ border.color: "#3870BA"
+ border.width: 2
+
+ Text {
+ id: logi
+ text: heartRate.message
+ anchors.centerIn: parent
+ color: "#3870BA"
+ }
+ }
+
+ Image {
+ id: background
+ width: 300
+ height: width
+ anchors.centerIn: parent
+ source: "blue_heart.png"
+ fillMode: Image.PreserveAspectFit
+ NumberAnimation on width {
+ running: heartRate.hr > 0;
+ duration: heartRate.hr/60*250;
+ from:300; to: 350;
+ loops: Animation.Infinite;
+ }
+
+ ParticleSystem {
+ id: systwo
+ anchors.fill: parent
+
+ ImageParticle {
+ system: systwo
+ id: cptwo
+ source: "star.png"
+ colorVariation: 0.4
+ color: "#000000FF"
+ }
+
+ Emitter {
+ //burst on click
+ id: burstytwo
+ system: systwo
+ enabled: true
+ x: 160
+ y: 150
+ emitRate: heartRate.hr*100
+ maximumEmitted: 4000
+ acceleration: AngleDirection {angleVariation: 360; magnitude: 360; }
+ size: 4
+ endSize: 8
+ sizeVariation: 4
+ }
+
+
+ }
+
+ }
+
+ Button {
+ id:stop
+ buttonWidth: parent.width
+ buttonHeight: 0.1*parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ text: "Stop Monitoring"
+ onButtonClick: {
+ burstytwo.enabled = false;
+ heartRate.disconnectService();
+ pageLoader.source = "results.qml";
+ }
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/results.qml b/examples/bluetooth/heartlistener/assets/results.qml
new file mode 100644
index 00000000..78c08873
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/results.qml
@@ -0,0 +1,290 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import "draw.js" as DrawGraph
+
+Rectangle {
+ id: results
+ color: "#F0EBED"
+
+ Component.onCompleted: heartRate.obtainResults()
+
+ function getTime() {
+ var t = heartRate.time;
+ var min = Math.floor(t/60);
+ var sec = t%60;
+ var r = min + " min " + sec + " sec "
+ return r;
+ }
+
+ function drawGraph() {
+ var b = plot.height/200;
+ var ctx = canvas1.getContext('2d');
+ ctx.beginPath()
+ ctx.moveTo(10, plot.height- (b*60))
+ var size = heartRate.measurementsSize();
+ var difference = (plot.width-topbar.width)/size;
+
+ for (var i = 0; i< size; i++) {
+ var value = heartRate.measurements(i);
+ if (i == 0) {
+ ctx.moveTo(10+2, (plot.height- (value*b) + 2));
+ ctx.rect((10 + i*difference), (plot.height- (value*b)), 4, 4);
+
+ }
+ else {
+ ctx.lineTo((10+2 + i*difference), (plot.height- (value*b) + 2));
+ ctx.rect((10 + i*difference), (plot.height- (value*b)), 4, 4);
+ }
+
+ }
+ ctx.fillStyle = "#3870BA"
+ ctx.fill()
+ ctx.strokeStyle = "#3870BA"
+ ctx.stroke()
+ ctx.closePath()
+ }
+
+ Rectangle {
+ id: res
+ width: parent.width
+ anchors.top: parent.top
+ height: 80
+ color: "#F0EBED"
+ border.color: "#3870BA"
+ border.width: 2
+ radius: 10
+ Text {
+ id: restText
+ color: "#3870BA"
+ font.pixelSize: 34
+ anchors.centerIn: parent
+ text: "Results"
+ }
+ }
+
+ Text {
+ id: topbar
+ text: "200"
+ anchors.left: parent.left
+ anchors.top: res.bottom
+ anchors.rightMargin: 4
+ color: "#3870BA"
+ z: 50
+ }
+
+ Rectangle {
+ id: level
+ anchors.left: topbar.right
+
+ anchors.top: res.bottom
+ height: ((results.height -(res.height + menuLast.height + start.height ))/2)
+ width: 3
+ color: "#3870BA"
+ }
+
+ Text {
+ id: middlebar
+ anchors.verticalCenter: level.verticalCenter
+ anchors.left: parent.left
+ text: "100"
+ color: "#3870BA"
+ z: 50
+ }
+
+ Rectangle{
+ id: downlevel
+ anchors.bottom: cover.top
+ width: parent.width
+ anchors.left: level.right
+ height: 3
+ color: "#3870BA"
+ z: 50
+ }
+
+ Rectangle {
+ id: plot
+ anchors.left: level.right
+ anchors.leftMargin: 15
+ width: results.width
+ height: ((parent.height-(res.height+menuLast.height+start.height))/2)
+
+ anchors.top: res.bottom
+ color: "#F0EBED"
+ Canvas {
+ id: canvas1
+ anchors.fill: parent
+ z: 150
+ onPaint: drawGraph()
+ }
+ }
+
+ Rectangle {
+ id: cover
+ anchors.top: plot.bottom
+ anchors.bottom: menuLast.top
+ width: parent.width
+ height: ((parent.height-(res.height+menuLast.height+start.height))/2)
+ color: "#F0EBED"
+ radius: 10
+ border.color: "#3870BA"
+ border.width: 2
+
+ Flickable {
+ id: scroll
+ anchors.fill: parent
+ anchors.margins: 5
+ clip: true
+ contentWidth: parent.width
+ contentHeight: stresult.height
+
+ Rectangle {
+ id: stresult
+ width: parent.width
+ height: (results.height - (res.height + menuLast.height + start.height - 100))
+ color: "#F0EBED"
+ radius: 10
+
+ Text {
+ id: averageHR
+ font.pixelSize: 30;
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+
+ color: "#3870BA"
+ text: "Average Heart Rate"
+ }
+
+ Text {
+ id: averageHRt
+ font.pixelSize: 40; font.bold: true
+ anchors.top: averageHR.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: heartRate.average
+ }
+
+ Text {
+ id: time
+ font.pixelSize: 30;
+ anchors.top: averageHRt.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: "Seconds measured "
+ }
+
+ Text {
+ id: timet
+ font.pixelSize: 40; font.bold: true
+ anchors.top: time.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: getTime()
+ }
+ Text {
+ id: maxi
+ font.pixelSize: 30;
+ anchors.top: timet.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: " Max || Min "
+ }
+
+ Text {
+ id: mini
+ font.pixelSize: 40; font.bold: true
+ anchors.top:maxi.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: " " + heartRate.maxHR + " || " + heartRate.minHR
+ }
+
+ Text {
+ id: calories
+ font.pixelSize: 30;
+ anchors.top: mini.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: " Calories "
+ }
+
+ Text {
+ id: caloriestext
+ font.pixelSize: 40; font.bold: true
+ anchors.top:calories.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 20
+ color: "#3870BA"
+ text: Math.floor(heartRate.calories)
+ }
+ }
+ }
+ }
+
+ Button {
+ id:menuLast
+ buttonWidth: parent.width
+ buttonHeight: 0.1*parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: start.top
+ text: "Menu"
+ onButtonClick: { pageLoader.source="main.qml"}
+ }
+
+ Button {
+ id:start
+ buttonWidth: parent.width
+ buttonHeight: 0.1*parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ text: "Start Monitoring"
+ onButtonClick: {
+ heartRate.connectToService(heartRate.deviceAddress());
+ pageLoader.source="monitor.qml";
+ }
+ }
+}
diff --git a/examples/bluetooth/heartlistener/assets/star.png b/examples/bluetooth/heartlistener/assets/star.png
new file mode 100644
index 00000000..defbde53
--- /dev/null
+++ b/examples/bluetooth/heartlistener/assets/star.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/deviceinfo.cpp b/examples/bluetooth/heartlistener/deviceinfo.cpp
new file mode 100644
index 00000000..656d6126
--- /dev/null
+++ b/examples/bluetooth/heartlistener/deviceinfo.cpp
@@ -0,0 +1,57 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceinfo.h"
+
+DeviceInfo::DeviceInfo(const QBluetoothDeviceInfo &device):
+ m_device(device)
+{
+ Q_EMIT deviceChanged();
+}
+
+QBluetoothDeviceInfo DeviceInfo::getDevice()
+{
+ return m_device;
+}
+
+void DeviceInfo::setDevice(const QBluetoothDeviceInfo &device)
+{
+ m_device = device;
+}
diff --git a/examples/bluetooth/heartlistener/deviceinfo.h b/examples/bluetooth/heartlistener/deviceinfo.h
new file mode 100644
index 00000000..94b0db80
--- /dev/null
+++ b/examples/bluetooth/heartlistener/deviceinfo.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEVICEINFO_H
+#define DEVICEINFO_H
+
+#include <QString>
+#include <QObject>
+#include <qbluetoothdeviceinfo.h>
+#include <qbluetoothaddress.h>
+
+class DeviceInfo: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString deviceName READ getName NOTIFY deviceChanged)
+ Q_PROPERTY(QString deviceAddress READ getAddress NOTIFY deviceChanged)
+public:
+ DeviceInfo(const QBluetoothDeviceInfo &device);
+ void setDevice(const QBluetoothDeviceInfo &device);
+ QString getName() { return m_device.name(); }
+ QString getAddress() { return m_device.address().toString(); }
+ QBluetoothDeviceInfo getDevice();
+
+signals:
+ void deviceChanged();
+
+private:
+ QBluetoothDeviceInfo m_device;
+};
+
+#endif // DEVICEINFO_H
diff --git a/examples/bluetooth/heartlistener/doc/images/hearratemonitor.png b/examples/bluetooth/heartlistener/doc/images/hearratemonitor.png
new file mode 100644
index 00000000..ed51ba86
--- /dev/null
+++ b/examples/bluetooth/heartlistener/doc/images/hearratemonitor.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/images/hearrateresults.png b/examples/bluetooth/heartlistener/doc/images/hearrateresults.png
new file mode 100644
index 00000000..2c961517
--- /dev/null
+++ b/examples/bluetooth/heartlistener/doc/images/hearrateresults.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/images/hearrateresults1.png b/examples/bluetooth/heartlistener/doc/images/hearrateresults1.png
new file mode 100644
index 00000000..7af63b57
--- /dev/null
+++ b/examples/bluetooth/heartlistener/doc/images/hearrateresults1.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/images/heartrateintro.png b/examples/bluetooth/heartlistener/doc/images/heartrateintro.png
new file mode 100644
index 00000000..fb0a7b34
--- /dev/null
+++ b/examples/bluetooth/heartlistener/doc/images/heartrateintro.png
Binary files differ
diff --git a/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc b/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc
new file mode 100644
index 00000000..fa63714a
--- /dev/null
+++ b/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example heartlistener
+ \title Bluetooth Low Energy Heart Listener example
+
+ The Bluetooth Low Energy (BLE) Heart Listener Example shows how to develop a Bluetooth
+ Low Energy applications using the Qt Bluetooth API. The application covers
+ the scanning for BLE devices, connecting to the BLE Heart Rate service and
+ receiving updates from the BLE heart belt. The BLE heart belt is required
+ for this application to work.
+
+ \image heartrateintro.png
+
+ The best and the safest approach is to do a service discovery for BLE device first and
+ then pick the heart rate service. Before that it is necessary to connect signals from
+ the QLowEnergyController class, which is responsible for the communication with the
+ BLE device.
+
+ \snippet heartlistener/heartrate.cpp Connect signals
+
+ After service scan is done and heart rate service found, the heart rate measurement
+ characteristic needs to be found and enabled for the notifications (advertisements).
+
+ \snippet heartlistener/heartrate.cpp Connecting to service
+
+ The enableNotifications(m_heartRateCharacteristic) method is the one that
+ will enable advertisement from the BLE device. Every time, when new update gets from
+ the BLE device (in our case heart rate belt) QLowEnergyController will emit
+ valueChanged(QLowEnergyCharacteristicInfo) method, which will invoke
+ receiveMeasurement(const QLowEnergyCharacteristicInfo &) slot.
+
+ \snippet heartlistener/heartrate.cpp Reading value
+
+ Every BLE device has its own structure of data that is advertising. In the code above,
+ the approach for checking the value structure is presented. The heart rate service contains
+ that information in the first 8 bits of the advertised value. For instance, first bit tells
+ the format of the value (is it 8 or 16 bit value), fourth tells does the heart belt provide
+ energy spenditure information, etc.
+
+ \snippet heartlistener/heartrate.cpp Error handling
+
+ In case an error occurs, QLowEnergyController will emit error, which can be read with
+ errorString() method. An error for BLE service can occur in the process of connecting to
+ the service. For BLE characteristics, an error can occur when trying to subscribe for the
+ notifications.
+
+ In the end, it is required to disconnect from the service.
+
+ \snippet heartlistener/heartrate.cpp Disconnecting from service
+
+ \image hearratemonitor.png
+ \image hearrateresults.png
+ \image hearrateresults1.png
+
+*/
+
diff --git a/examples/bluetooth/heartlistener/heartlistener.pro b/examples/bluetooth/heartlistener/heartlistener.pro
new file mode 100644
index 00000000..7856b64e
--- /dev/null
+++ b/examples/bluetooth/heartlistener/heartlistener.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+TARGET = heartlistener
+
+QT += quick bluetooth
+
+# Input
+HEADERS += deviceinfo.h \
+ heartrate.h
+SOURCES += deviceinfo.cpp \
+ heartrate.cpp \
+ main.cpp
+
+OTHER_FILES += assets/*.qml \
+ assets/*.js
+
+RESOURCES += \
+ resources.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/heartlistener
+INSTALLS += target
diff --git a/examples/bluetooth/heartlistener/heartrate.cpp b/examples/bluetooth/heartlistener/heartrate.cpp
new file mode 100644
index 00000000..a80f0c0c
--- /dev/null
+++ b/examples/bluetooth/heartlistener/heartrate.cpp
@@ -0,0 +1,397 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "heartrate.h"
+
+#include <qbluetoothaddress.h>
+#include <qbluetoothservicediscoveryagent.h>
+#include <qbluetoothserviceinfo.h>
+#include <qbluetoothlocaldevice.h>
+#include <qlowenergyserviceinfo.h>
+#include <qlowenergycharacteristicinfo.h>
+#include <qbluetoothuuid.h>
+#include <QTimer>
+
+HeartRate::HeartRate():
+ m_currentDevice(QBluetoothDeviceInfo()), foundHeartRateService(false), foundHeartRateCharacteristic(false), m_HRMeasurement(0), m_max(0), m_min(0), calories(0), m_leInfo(0), timer(0)
+{
+ m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent();
+ m_serviceDiscoveryAgent = new QBluetoothServiceDiscoveryAgent(QBluetoothAddress());
+
+ connect(m_deviceDiscoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
+ this, SLOT(addDevice(const QBluetoothDeviceInfo&)));
+ connect(m_deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
+ this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
+ connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
+
+ connect(m_serviceDiscoveryAgent, SIGNAL(serviceDiscovered(const QLowEnergyServiceInfo&)),
+ this, SLOT(addLowEnergyService(const QLowEnergyServiceInfo&)));
+ connect(m_serviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(serviceScanDone()));
+ connect(m_serviceDiscoveryAgent, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)),
+ this, SLOT(serviceScanError(QBluetoothServiceDiscoveryAgent::Error)));
+}
+
+HeartRate::~HeartRate()
+{
+ delete m_deviceDiscoveryAgent;
+ delete m_serviceDiscoveryAgent;
+ delete m_leInfo;
+ delete timer;
+ qDeleteAll(m_devices);
+ m_devices.clear();
+}
+
+void HeartRate::deviceSearch()
+{
+ m_devices.clear();
+ m_deviceDiscoveryAgent->start();
+ setMessage("Scanning for devices...");
+}
+
+void HeartRate::addDevice(const QBluetoothDeviceInfo &device)
+{
+ if (device.coreConfiguration() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
+ QBluetoothLocalDevice localDevice;
+ QBluetoothLocalDevice::Pairing pairingStatus = localDevice.pairingStatus(device.address());
+ if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired )
+ qWarning() << "Discovered LE Device name: " << device.name() << " Address: " << device.address().toString() << " Paired";
+ else
+ qWarning() << "Discovered LE Device name: " << device.name() << " Address: " << device.address().toString() << " not Paired";
+ DeviceInfo *dev = new DeviceInfo(device);
+ m_devices.append(dev);
+ setMessage("Low Energy device found. Scanning for more...");
+ }
+}
+
+void HeartRate::scanFinished()
+{
+ if (m_devices.size() == 0)
+ setMessage("No Low Energy devices found");
+ Q_EMIT nameChanged();
+}
+
+void HeartRate::setMessage(QString message)
+{
+ m_info = message;
+ Q_EMIT messageChanged();
+}
+
+QString HeartRate::message() const
+{
+ return m_info;
+}
+
+QVariant HeartRate::name()
+{
+ return QVariant::fromValue(m_devices);
+}
+
+void HeartRate::connectToService(const QString &address)
+{
+ bool deviceHere = false;
+ for (int i = 0; i<m_devices.size(); i++) {
+ if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
+ m_currentDevice.setDevice(((DeviceInfo*)m_devices.at(i))->getDevice());
+ setMessage("Device selected.");
+ deviceHere = true;
+ }
+ }
+ // This in case we are running demo mode
+ if (!deviceHere)
+ startDemo();
+ else {
+ QBluetoothDeviceInfo device = m_currentDevice.getDevice();
+ //! [Connect signals]
+ m_serviceDiscoveryAgent->setRemoteAddress(device.address());
+ m_serviceDiscoveryAgent->start();
+ if (!m_leInfo) {
+ m_leInfo = new QLowEnergyController();
+ connect(m_leInfo, SIGNAL(connected(QLowEnergyServiceInfo)), this, SLOT(serviceConnected(QLowEnergyServiceInfo)));
+ connect(m_leInfo, SIGNAL(disconnected(QLowEnergyServiceInfo)), this, SLOT(serviceDisconnected(QLowEnergyServiceInfo)));
+ connect(m_leInfo, SIGNAL(error(QLowEnergyServiceInfo)), this, SLOT(errorReceived(QLowEnergyServiceInfo)));
+ connect(m_leInfo, SIGNAL(error(QLowEnergyCharacteristicInfo)), this, SLOT(errorReceivedCharacteristic(QLowEnergyCharacteristicInfo)));
+ connect(m_leInfo, SIGNAL(valueChanged(QLowEnergyCharacteristicInfo)), this, SLOT(receiveMeasurement(QLowEnergyCharacteristicInfo)));
+ }
+ //! [Connect signals]
+ }
+}
+
+void HeartRate::addLowEnergyService(const QLowEnergyServiceInfo &gatt)
+{
+ if (gatt.uuid() == QBluetoothUuid::HeartRate) {
+ setMessage("Heart Rate service discovered. Waiting for service scan to be done...");
+ m_heartRateService = QLowEnergyServiceInfo(gatt);
+ foundHeartRateService = true;
+ }
+}
+
+//! [Connecting to service]
+void HeartRate::serviceScanDone()
+{
+ //If HeartBelt is not connected (installed on the body) this message will stay.
+ setMessage("Connecting to service... Be patient...");
+ //It is not advisable to connect to BLE device right after scanning.
+ if (foundHeartRateService)
+ QTimer::singleShot(3000, this, SLOT(startConnection()));
+ else
+ setMessage("Heart Rate Service not found. Make sure your device is paired.");
+}
+
+void HeartRate::startConnection()
+{
+ // HeartRate belt that this application was using had a random device address. This is only needed
+ // for Linux platform.
+ // m_heartRateService.setRandomAddress();
+ m_leInfo->connectToService(m_heartRateService);
+}
+
+void HeartRate::serviceConnected(const QLowEnergyServiceInfo &leService)
+{
+ setMessage("Connected to service. Waiting for updates");
+ if (leService.uuid() == QBluetoothUuid::HeartRate) {
+ for ( int i = 0; i<leService.characteristics().size(); i++) {
+ if (leService.characteristics().at(i).uuid() == QBluetoothUuid::HeartRateMeasurement) {
+ m_start = QDateTime::currentDateTime();
+ m_heartRateCharacteristic = QLowEnergyCharacteristicInfo(leService.characteristics().at(i));
+ m_leInfo->enableNotifications(m_heartRateCharacteristic);
+ foundHeartRateCharacteristic = true;
+ }
+ }
+ }
+}
+//! [Connecting to service]
+
+void HeartRate::receiveMeasurement(const QLowEnergyCharacteristicInfo &characteristic)
+{
+ m_heartRateCharacteristic = QLowEnergyCharacteristicInfo(characteristic);
+ //! [Reading value]
+ QString val;
+ qint16 energy_expended = 0;
+ int flags = 0;
+ int index = 0;
+ val[0] = m_heartRateCharacteristic.value().at(index++);
+ // Each Heart Belt has its own settings and fetarues, besides heart rate measurement
+ // By checking the flags we can determine whether it has energy feature. We will go through the array
+ // of the characters in the characteristic value.
+ if (val.toUInt(0, 16) > 3)
+ flags = val.toUInt(0, 16);
+ else {
+ val[1] = m_heartRateCharacteristic.value().at(index++);
+ flags = val.toUInt(0, 16);
+ }
+ QString value;
+ value[0] = m_heartRateCharacteristic.value().at(index++);
+ value[1] = m_heartRateCharacteristic.value().at(index++);
+ m_HRMeasurement = value.toUInt(0, 16);
+ //! [Reading value]
+ m_measurements.append(m_HRMeasurement);
+ // The following flags are used to determine what kind of value is being sent from the device.
+ // FLAGS field bit mask values
+ qint8 heartRateValueFormat = 1;// 0
+ qint8 energyExpendedFeature = 8;// 3
+ bool hrDataFormat = false;
+ bool energyExpendedFeatureSupported = false;
+
+ hrDataFormat = ((flags & heartRateValueFormat) != heartRateValueFormat); // 0 means 8 bit, 1 means 16 bit
+ energyExpendedFeatureSupported = ((flags & energyExpendedFeature) == 0);
+ if (!hrDataFormat)
+ qWarning() << "XXXX 16 bit heart rate measurement data encountered!";
+ if (energyExpendedFeatureSupported) {
+ QString energy;
+ int counter1 = 0;
+ for (int i = index; i < (m_heartRateCharacteristic.value().size() - 1); i++) {
+ if (counter1 > 3)
+ break;
+ energy[i] = m_heartRateCharacteristic.value().at(i);
+ counter1 ++;
+ }
+ energy_expended = energy.toUInt(0, 16);
+ index = index + 2;
+ }
+ qWarning() << "Used energy: " << energy_expended;
+ Q_EMIT hrChanged();
+}
+
+int HeartRate::hR() const
+{
+ return m_HRMeasurement;
+}
+
+//! [Error handling]
+void HeartRate::errorReceived(const QLowEnergyServiceInfo &leService)
+{
+ setMessage(QStringLiteral("Error: ") + leService.errorString());
+}
+
+void HeartRate::errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &leCharacteristic)
+{
+ setMessage(QStringLiteral("Error: ") + leCharacteristic.errorString());
+}
+//! [Error handling]
+
+void HeartRate::disconnectService()
+{
+ if (foundHeartRateCharacteristic) {
+ m_stop = QDateTime::currentDateTime();
+ //! [Disconnecting from service]
+ m_leInfo->disableNotifications(m_heartRateCharacteristic);
+ m_leInfo->disconnectFromService();
+ //! [Disconnecting from service]
+ }
+ else if (m_devices.size() == 0) {
+ m_stop = QDateTime::currentDateTime();
+ timer->stop();
+ timer = 0;
+ }
+ foundHeartRateCharacteristic = false;
+ foundHeartRateService = false;
+}
+
+void HeartRate::obtainResults()
+{
+ Q_EMIT timeChanged();
+ Q_EMIT averageChanged();
+ Q_EMIT caloriesChanged();
+}
+
+int HeartRate::time()
+{
+ return m_start.secsTo(m_stop);
+}
+
+int HeartRate::maxHR() const
+{
+ return m_max;
+}
+
+int HeartRate::minHR() const
+{
+ return m_min;
+}
+
+float HeartRate::average()
+{
+ if (m_measurements.size() == 0)
+ return 0;
+ else {
+ m_max = 0;
+ m_min = 1000;
+ int sum = 0;
+ for (int i=0; i< m_measurements.size(); i++) {
+ sum += (int) m_measurements.value(i);
+ if (((int)m_measurements.value(i)) > m_max)
+ m_max = (int)m_measurements.value(i);
+ if (((int)m_measurements.value(i)) < m_min)
+ m_min = (int)m_measurements.value(i);
+ }
+ return sum/m_measurements.size();
+ }
+}
+
+int HeartRate::measurements(int index)
+{
+ if (index> m_measurements.size())
+ return 0;
+ else
+ return (int)m_measurements.value(index);
+}
+
+int HeartRate::measurementsSize()
+{
+ return m_measurements.size();
+}
+
+QString HeartRate::deviceAddress()
+{
+ return m_currentDevice.getDevice().address().toString();
+}
+
+float HeartRate::caloriesCalculation()
+{
+ calories = ((-55.0969 + (0.6309 * average()) + (0.1988 * 94) + (0.2017 * 24)) / 4.184) * 60 * time()/3600 ;
+ return calories;
+}
+
+void HeartRate::serviceDisconnected(const QLowEnergyServiceInfo &service)
+{
+ setMessage("Heart Rate service disconnected");
+ qWarning() << "Service disconnected: " << service.uuid();
+}
+
+int HeartRate::numDevices() const
+{
+ return m_devices.size();
+}
+
+void HeartRate::startDemo()
+{
+ m_start = QDateTime::currentDateTime();
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(receiveDemo()));
+ timer->start(1000);
+ setMessage("This is Demo mode");
+}
+
+void HeartRate::receiveDemo()
+{
+ m_HRMeasurement = 60;
+ m_measurements.append(m_HRMeasurement);
+ Q_EMIT hrChanged();
+}
+
+void HeartRate::serviceScanError(QBluetoothServiceDiscoveryAgent::Error error)
+{
+ if (error == QBluetoothServiceDiscoveryAgent::PoweredOffError)
+ setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery.");
+ else if (error == QBluetoothServiceDiscoveryAgent::InputOutputError)
+ setMessage("Writing or reading from the device resulted in an error.");
+ else
+ setMessage("An unknown error has occurred.");
+}
+
+void HeartRate::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
+{
+ if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
+ setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery.");
+ else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
+ setMessage("Writing or reading from the device resulted in an error.");
+ else
+ setMessage("An unknown error has occurred.");
+}
diff --git a/examples/bluetooth/heartlistener/heartrate.h b/examples/bluetooth/heartlistener/heartrate.h
new file mode 100644
index 00000000..e7d75666
--- /dev/null
+++ b/examples/bluetooth/heartlistener/heartrate.h
@@ -0,0 +1,144 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HEARTRATE_H
+#define HEARTRATE_H
+
+#include <QString>
+#include <QObject>
+#include <QList>
+#include <QtCore/QDebug>
+#include <QDateTime>
+#include <QVector>
+#include <QTimer>
+#include "deviceinfo.h"
+#include <qbluetoothglobal.h>
+#include <qbluetoothlocaldevice.h>
+#include <qbluetoothdeviceinfo.h>
+#include "qlowenergyserviceinfo.h"
+#include "qlowenergycontroller.h"
+#include <QBluetoothServiceDiscoveryAgent>
+#include <QBluetoothDeviceDiscoveryAgent>
+
+QT_FORWARD_DECLARE_CLASS (QLowEnergyServiceInfo)
+QT_FORWARD_DECLARE_CLASS (QLowEnergyCharacteristicInfo)
+QT_FORWARD_DECLARE_CLASS (QLowEnergyController)
+
+QT_USE_NAMESPACE
+class HeartRate: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QVariant name READ name NOTIFY nameChanged)
+ Q_PROPERTY(QString message READ message NOTIFY messageChanged)
+ Q_PROPERTY(int hr READ hR NOTIFY hrChanged)
+ Q_PROPERTY(int maxHR READ maxHR NOTIFY averageChanged)
+ Q_PROPERTY(int minHR READ minHR NOTIFY averageChanged)
+ Q_PROPERTY(float average READ average NOTIFY averageChanged)
+ Q_PROPERTY(int time READ time NOTIFY timeChanged)
+ Q_PROPERTY(float calories READ caloriesCalculation NOTIFY caloriesChanged)
+
+public:
+ HeartRate();
+ ~HeartRate();
+ void setMessage(QString message);
+ QString message() const;
+ QVariant name();
+ int hR() const;
+ int time();
+ float average();
+ int maxHR() const;
+ int minHR() const;
+ float caloriesCalculation();
+
+public slots:
+ void deviceSearch();
+ void addDevice(const QBluetoothDeviceInfo&);
+ void deviceScanError(QBluetoothDeviceDiscoveryAgent::Error);
+ void scanFinished();
+ void connectToService(const QString &address);
+ void addLowEnergyService(const QLowEnergyServiceInfo&);
+ void serviceScanDone();
+ void serviceScanError(QBluetoothServiceDiscoveryAgent::Error);
+ void serviceConnected(const QLowEnergyServiceInfo &);
+ void receiveMeasurement(const QLowEnergyCharacteristicInfo &);
+ void errorReceived(const QLowEnergyServiceInfo &);
+ void errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &);
+ void serviceDisconnected(const QLowEnergyServiceInfo &);
+ void disconnectService();
+ void obtainResults();
+ void startConnection();
+ int measurements(int index);
+ int measurementsSize();
+ QString deviceAddress();
+ int numDevices() const;
+ void startDemo();
+ void receiveDemo();
+
+Q_SIGNALS:
+ void messageChanged();
+ void nameChanged();
+ void hrChanged();
+ void averageChanged();
+ void timeChanged();
+ void caloriesChanged();
+
+private:
+ DeviceInfo m_currentDevice;
+ QBluetoothServiceDiscoveryAgent *m_serviceDiscoveryAgent;
+ QBluetoothDeviceDiscoveryAgent *m_deviceDiscoveryAgent;
+ QLowEnergyCharacteristicInfo m_heartRateCharacteristic;
+ QList<QObject*> m_devices;
+ QString m_info;
+ QLowEnergyServiceInfo m_heartRateService;
+ bool foundHeartRateService;
+ bool foundHeartRateCharacteristic;
+ int m_HRMeasurement;
+ QVector<qint8> m_measurements;
+ QDateTime m_start;
+ QDateTime m_stop;
+ int m_max;
+ int m_min;
+ QVector<QDateTime> m_timestamps;
+ float calories;
+ QLowEnergyController *m_leInfo;
+ QTimer *timer; // for demo application
+};
+
+#endif // HEARTRATE_H
diff --git a/examples/bluetooth/heartlistener/main.cpp b/examples/bluetooth/heartlistener/main.cpp
new file mode 100644
index 00000000..3ea3a652
--- /dev/null
+++ b/examples/bluetooth/heartlistener/main.cpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QQmlContext>
+#include <QGuiApplication>
+#include <QQuickView>
+#include "heartrate.h"
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ HeartRate heartRate;
+ QQuickView *view = new QQuickView;
+ view->rootContext()->setContextProperty("heartRate", &heartRate);
+ view->setSource(QUrl("qrc:/assets/main.qml"));
+ view->setResizeMode(QQuickView::SizeRootObjectToView);
+ view->show();
+ return app.exec();
+
+}
diff --git a/examples/bluetooth/heartlistener/resources.qrc b/examples/bluetooth/heartlistener/resources.qrc
new file mode 100644
index 00000000..ac6f9c83
--- /dev/null
+++ b/examples/bluetooth/heartlistener/resources.qrc
@@ -0,0 +1,16 @@
+<RCC>
+ <qresource prefix="/">
+ <file>assets/blue_heart.png</file>
+ <file>assets/busy_dark.png</file>
+ <file>assets/Button.qml</file>
+ <file>assets/dialog.qml</file>
+ <file>assets/draw.js</file>
+ <file>assets/home.qml</file>
+ <file>assets/main.qml</file>
+ <file>assets/monitor.qml</file>
+ <file>assets/Point.qml</file>
+ <file>assets/results.qml</file>
+ <file>assets/star.png</file>
+ <file>assets/blue_heart_small.png</file>
+ </qresource>
+</RCC>