Skip to main content
Samsung Developer Program

Create and Test a Sample Web AppĀ Using Heart Rate Sensor

Create and Test a Sample Web App Using Heart Rate Sensor
This section describes how to build a sample Web application that runs on Gear devices and monitors the user's heart rate.

Create the Sample Web App

Before you create the sample web app, make sure you meet the following prerequisites.

Prerequisites

Create a Tizen Project

  1. Click File > New >Tizen Project
    HeartRateNewProject.PNG

  2.  In the New Tizen Project wizard, select Template, and click Next.
    HeartRateNewTemplate.PNG
  3. Select the Profile & Version as Wearable and Wearable v2.3.1, and click Next.
    HeartRateProfileVersion.PNG
  4. Select the Application Type as Web application, and click Next.
    HeartRateWebAppType.PNG
  5. Select the Template as TAU Basic and click Next.
    HeartRateTAUBasic.PNG
  6. Enter the Project name, and click Finish.

    HeartRateProjectName.PNG

You can see the created project in the Project Explorer View. The most important files and folders are:

css Folder for cascading style sheet (CSS) files used by the application to style its content
js Folder for JavaScript files used by the application to implement its functional logic
config.xml Application configuration file used by the platform to install and launch the application
icon.png Application icon file used by the platform to represent the application
index.html Main HTML file for the layout of the application screen

Add Required Privileges 

  • To protect the device system and user private data effectively, the Tizen security architecture is based on privileges and application signing of the Linux basic security model, which includes process isolation and mandatory access control.
  • Tizen provides API-level access control for security-sensitive operations. If this is not used correctly, it can harm user privacy and system stability. Therefore, applications that use such sensitive APIs must declare the required privileges in the config.xml file.

To access Heart Rate Sensor, declare the following privilege in the config.xml file:

http://tizen.org/privilege/healthinfo

Add required privileges in order to access heart rate sensor data.

  1.   In the Project Explorer window, select config.xml.

    HeartRate_configxml.PNG
  2. Check the privileges tab, and add a new privilege:
    HeartRateAddNewPrivilege.PNG

Add Image Resources 

  1. In your project, create a new folder titled images.
  2. Download the heart.png file.
  3. Copy the heart.png file to the images folder.  

    HeartRateSaveHeartIcon.PNG
     
  4.  Define the application layout by opening index.html and adding HTML code:
    1. Define init() in the onload of the document in order to execute init() immediately after the page has been loaded. ⓐ
    2. Change the title of the application. ⓑ
    3. Define the UI to show the Heart Rate value. ⓒ
    4. Define the UI to show the heart image. ⓓ
    5. Define the UI to display the measuring status. ⓔ
    6. Create a UI button to control the sensor operation.
      <body onload="init()"> ⓐ
      <div class="ui-page ui-page-active" id="main">
      <div class="ui-header">
      <h2 class="ui-title">Heart Rate Monitor</h2> ⓑ
      </div>
      <div class="ui-content">
      <div id="heart-rate-value"></div> ⓒ
      <div id="heart">
      <div id="heart-img"></div> ⓓ
      </div>
      <div id="measuring-info" class="hide"> ⓔ
      Measuring...
      </div>
      </div>
      <footer class="ui-footer ui-bottom-button">
      <a id="hrm-control-btn" class="ui-btn">Start</a> ⓕ
      </footer>
      </div>
    7. Create a TAU UI component ui-page to create a second page that displays information to the user when the sensor is not working.  ⓖ
    8. Create TAU UI component Bottom Button (ui-bottom-button), which displays Back text.  ⓗ
      1. Create a title for the second page by using a ui-title TAU UI component.  ⓧ

      2. Create a UI to display information text.  ⓨ

        <div class="ui-page" id="info"> ⓖ
            <div class="ui-header">
                <h2 class="ui-title">HRM Info</h2> ⓧ
            </div>
            <div class="ui-content">
                <div class="info-text"> ⓨ
                    Try again. Clean the sensor, wear the watch properly.
                </div>
            </div>
            <footer class="ui-footer ui-bottom-button">
                <a id="info-back-btn" class="ui-btn">Back</a> ⓗ
            </footer>
        </div>
        
        
    9. TAU Theme: tau.circle.(min).css OR tau/wearable/js/tau.min.js 
      It is mandatory for wearable devices, as it imports themes for wearables. Ⓘ

    10. circle-helper.js contains TAU helper modules for displaying circular UI components. ⓙ

    11. Load your javascript file. ⓚ

  5. lowBatteryCheck.js is a default .js file that is available with the TAU template.
    If the device battery level reaches below a set threshold, it closes the app. Usually, the platform closes the app when the device is in low-power mode and turns off the device. ⓛ

        <script type="text/javascript" src="lib/tau/wearable/js/tau.min.js"></script> Ⓘ
        <script type="text/javascript" src="js/circle-helper.js"></script> ⓙ
        <script src="./js/app.js"></script> ⓚ
        <script src="lowBatteryCheck.js"></script> ⓛ
    </body>
    </html>
    
    

Add Styles to HTML Elements 

Add styles to HTML elements to manage the styles and positioning of UI elements. CSS files specify the layout and style of the Web application.

# is an ID selector Used to select a single specific element with a unique ID.
. is a class selector Used to target multiple elements with a particular class name.
  1. In Project Explorer, open the styles.css file and add the following code:
     
    @keyframes

    The @keyframes rule specifies the animation code. Specify when a style change will happen in percent (from 0% to 100%).  ⓐ

    The sample Web app specifies the image size at 0%, 50%, and 100%, and changes the image to a smaller size of 25% and 75%.

    @Media queries Media queries allow you to apply the CSS differently according to the type of device. To define media queries for a circular Tizen device in the CSS, use the format:
    @media screen and (-tizen-geometric-shape: circle) {<styles>} ⓑ
     
    .ui-title {
        font-size: 25px !important;
    }
    
    .ui-content {
        font-size: 20px;
    }
    
    #heart-rate-value {
        position: absolute;
        text-align: center;
        width: 100%;
        height: 20%;
        font-size: 17vh;
        font-weight: bold;
        z-index: 100;
        margin-top: 15%;
        color: #ffffff;
    }
    
    #heart {
        position: absolute;
        width: 100%;
        height: 85%;
    }
    
    #heart-img {
        margin: 5% auto;
        background-image: url(../images/heart.png);
        background-position: center;
        background-size: cover;
        width: 60%;
        height: 60%;
    }
    
    #measuring-info {
        position: absolute;
        float: left;
        margin-left: 1%;
        color: white;
        font-size: 20px;
    }
    
    .show {
        display: inline-block;
    }
    
    .hide {
        display: none;
    }
    
    .ui-footer {
        background-color: transparent;
    }
    
    .info-text {
        text-align: left;
        color: #ffffff;
        font-size: 24px;
    }
    
    @-webkit-keyframes heartMove360 {  ⓐ
        0%, 50%, 100% {
            width: 35%;
            height: 35%;
        }
        25%, 75% {
            width: 45%;
            height: 45%;
        }
    }
    
    @media screen and (-tizen-geometric-shape: circle) {  ⓑ
        .ui-header {
            height: 90px;
        }
        
        #measuring-info {
            position: relative;
            margin-left: 7%;
        }
        
        #heart-img {
            width: 45%;
            height: 45%;
        }
        
        .animate {
            -webkit-animation: heartMove360 1.5s infinite;
        }
        
        .ui-footer {
            height: 20%;
        }
        
        .info-text {
            text-align: center;
            margin-left: 5%;
            margin-right: 5%;
        }
    }
  2. Implement the app’s functional logic by opening the app.js file in Project Explorer and adding JavaScript code to define the variables for measuring heart rate.
     
    INFO_SETTIMEOUT_DELAY

    After starting the HRM sensor, it takes several seconds to get the heart rate data. A timer is started when the sensor is started, but we do not yet get any data. The text “Measuring…” is displayed to the user. ⓐ

    INFO_SHOW_DELAY A timer is started when the info page is shown. After the specified time interval (in milliseconds), it is redirected to the Main page. ⓑ
    TEXT_STOP To set the value of the bottom button to Stop. ⓒ
    TEXT_START To set the value of the bottom button to Start. ⓒ
    heartRateEl Variable that has the HR sensor value and updates the value of <div> heart-rate-value. ⓔ
    heartImg Variable to add animation to the heart image. ⓕ
    infoBackBtn Variable for <div>info-back-btn ⓖ
    hrmControlBtn Variable for <div> hrm-control-btn ⓗ
    measuringText Variable to change the label of <div> measuring-info Ⓘ
    sensorStarted Boolean variable to toggle the value between started and stopped. ⓙ
    /*global tau*/
    /*exported init*/
    
    var INFO_SETTIMEOUT_DELAY = 10000;  ⓐ
    var INFO_SHOW_DELAY = 10000;  ⓑ
    var TEXT_STOP = 'Stop';  ⓒ
    var TEXT_START = 'Start';  ⓓ
    
    var heartRateEl;  ⓔ
    var heartImg;  ⓕ
    var infoBackBtn;  ⓖ
    var hrmControlBtn;  ⓗ
    var measuringText;  Ⓘ
    
    var infoTimeoutEnd = 0;
    var infoTimeout = 0;
    
    var sensorStarted = false;  ⓙ
    
    /*
     * Function invoked on onload event
     */
    function init() 
    {
        console.log("init() called...");
        heartRateEl = document.getElementById('heart-rate-value');
        heartImg = document.getElementById('heart-img');
        infoBackBtn = document.getElementById('info-back-btn');
        hrmControlBtn= document.getElementById('hrm-control-btn');
        measuringText = document.getElementById('measuring-info');
        
        //Registering click event handler for buttons.
        infoBackBtn.addEventListener('click', onInfoBackBtnClick);
        hrmControlBtn.addEventListener('click', onhrmControlBtnClick);
    }
    
    /*
     * Click event handler for HRM sensor Start/Stop
     * Toggles the sensor state.
     */
    function onhrmControlBtnClick() {
        console.log("onhrmControlBtnClick() called...");
        
        if (hrmControlBtn.innerHTML === TEXT_START){
            console.log("info on button = start");
            startSensor();
        } else {
            console.log("info on button = stop");
            stopSensor();
        }
    }
    
    /*
     * Starts the HRM sensor and registers a change listener.
     * Update the UI: Shows measuring text, and change button text to Stop.
     */    
    function startSensor() {
        console.log("start sensor() called...");
        sensorStarted = true;
        clearTimers();
        measuringText.classList.remove('hide');
        measuringText.classList.add('show');
        hrmControlBtn.innerHTML = TEXT_STOP;
        
        tizen.humanactivitymonitor.start('HRM', onHeartRateDataChange, onerrorCB);
    }
    
    /*
     * Clear the timers if running for handling the information popup.
     */
    function clearTimers() {
        console.log("Clear timers() called");
        window.clearTimeout(infoTimeout);
        window.clearTimeout(infoTimeoutEnd);
        infoTimeout = 0;
        infoTimeoutEnd = 0;
    }
    
    /*
     * Callback function Handles change event on current heart rate.
     * 
     */
    function onHeartRateDataChange(heartRateInfo) {
        console.log("onHeartRateDataChange() called...");
        if (!sensorStarted){
            return;
        }
        
        var rate = heartRateInfo.heartRate;
        var activePage = document.getElementsByClassName('ui-page-active')[0];
        var activePageId = activePage ? activePage.id : '';
    
        /*
         * If heart rate value is invalid-
         * Remove heart image animation, 
         * Displays measuring text and start a timer to show the information popup after 10 seconds. 
         */
         
        if (rate < 1) {
            console.log("Heart rate value < 1");
            rate = 0;
            heartRateEl.innerHTML = '';
            heartImg.classList.remove('animate');
            measuringText.classList.remove('hide');
            measuringText.classList.add('show');
    
            /* Start a timer when sensor is started but not able to measure the heart rate
             * showMeasuringInfo() function will be execute after 10 sec and will show a info popup.
             */
             
            if (activePageId === 'main' && infoTimeout === 0) {
                infoTimeout = window.setTimeout(showMeasuringInfo, INFO_SETTIMEOUT_DELAY);
            }
        } else {
            /*
             * If heart rate value is valid
             * Clear all the timers to  handle info popup
             * Hides measuring text
             * Start the animation on heart image
             * and displays the heart rate value.
             */
            clearTimers();
            hideMeasuringInfo();
            console.log("heartRateEl is valid information...");
            if (!heartImg.classList.contains('animate')) {
                heartImg.classList.add('animate');
                measuringText.classList.remove('show');
                measuringText.classList.add('hide');
            }
            heartRateEl.innerHTML = rate;
        }
    }
    
    /* 
     * Call back when an error occurs */
     
    function onerrorCB(error) {
        console.log("Error name:"+error.name + ", message: "+error.message);
    }
    
    /*
     * Displays information popup.
     */
    function showMeasuringInfo() {
        console.log("showMeasuringInfo() called..");
        infoTimeout = 0;
        tau.changePage('#info');
        
        /* Start a timer when info popup is shown
         * hideMeasuringInfo() function will be execute after 10 sec and which will redirect to main page.
         */
        infoTimeoutEnd = window.setTimeout(hideMeasuringInfo, INFO_SHOW_DELAY);
    }
    
    /*
     * Hides information popup, redirects to main page.
     */
    function hideMeasuringInfo() {
        console.log("hideMeasuringInfo() called..");
        tau.changePage('#main');
        infoTimeoutEnd = 0;
    }
    
    /*
     * Stops the sensor
     * Clears timers (to handle info popup)
     * Update the UI: Hides measuring text, stop animation on heart image and change button text to Start.
     */    
    function stopSensor() {
        console.log("stopSensor() called...");
        sensorStarted = false;
        heartImg.classList.remove('animate');
        measuringText.classList.remove('show');
        measuringText.classList.add('hide');
        
        clearTimers();    
        
        tizen.humanactivitymonitor.stop("HRM");
        hrmControlBtn.innerHTML = TEXT_START;
    }
    
    /*
     * Click event handler for back button on info page
     * Hides the information popup and redirects to main page.
     */
    function onInfoBackBtnClick() {
        console.log("onInfoBackBtnClick() called...");
        window.clearTimeout(infoTimeoutEnd);
        infoTimeoutEnd = 0;
        tau.changePage('#main');
    }
    
    ( function () {
        
        window.addEventListener( 'tizenhwkey', function( ev ) {
            if( ev.keyName === "back" ) {
            var page = document.getElementsByClassName( 'ui-page-active' )[0], pageid = page ? page.id : "";
                if( pageid === "main" ) {
                    try {
                        tizen.humanactivitymonitor.stop("HRM");
                        tizen.application.getCurrentApplication().exit();
                    } catch (ignore) {
                    }
                } else {
                    window.history.back();
                }
            }
        } );
        
    } () );

Connect a Gear Device via Wi-Fi

To connect a Gear S2 or S3 device to a host PC, you need a wireless access point (Wi-Fi with no firewalls). Both the Gear device and the host PC must be connected to the same Wi-Fi.

Set Up the Connection in the Gear Device 

  1. Go to Settings > Connections and turn on Wi-Fi.
  2. Go to Settings > Gear Info and turn on Debugging.
  3. Reboot the Gear device.
Connect the Gear Device to the Wireless Access Point 
  1. In the Wi-Fi menu, find the wireless access point and connect to it.
  2. Go to Settings > Connections > Bluetooth and turn off Bluetooth.
  3. After the Gear device UI indicates it is connected, find the IP address assigned to the Gear device via DHCP.
    Go to Settings > Connections > Wi-Fi> Wi-Fi Networks > Your Wi-Fi connection > IP Address
    Note the IP address.
    IPAddressforGearDevice.PNG

Connect to the Gear Device 

You can connect either of through a terminal or from within Tizen Studio.

Through the Terminal  

Connect to the Gear device by using the following command in a terminal:

$ sdb connect [Wi-Fi network IP address]:26101

For example:

$ sdb connect 192.168.0.130:26101

From Within Tizen Studio 
  1. Go to Window > Show View > Connection Explorer
    This makes the Connection Explorer view visible in the right panel of Tizen Studio.
  2. In the Connection Explorer view toolbar, click the Remote Device Manager icon.
    The Remote Device Manager lists all remote devices on the host system's subnet. If the IP address of the Gear device is not listed, verify that you have performed all previous steps correctly.
    ConnectGearDeviceUsingTizen.PNG
  3. In the Remote Device Manager:
    1. Select the listed remote device with the IP address assigned to the Gear device.
    2. Click Connect.

Note: Later, you can add remote devices and change remote device information in the Remote Device Manager window:

  • To add remote device information: Click New, and enter the Name, IP, and Port field entries of the new remote device.
  • To modify remote device information: Select the device, click Edit, and modify the Name, IP, and/or Port field entries.
  1. A popup notice will be displayed in the Gear device. Accept the RSA key.

Create Author and Distributor Certificates and Permit Install Applications 

To run a Web application on a commercial device, you must create Tizen author and distributor certificates from the Samsung certificate center.

Generate a Certificate Profile

  1. In Tizen Studio, select Tools > Certificate Manager.
    TizenCertificateProfile.PNG
  2. Click the Plus icon.
  3. Click Type of certificate profile.
    TypeofCertificateProfile.PNG
  4. Click Close.
    CreateCertificateProfile.PNG
  5. Select Mobile / Wearable type of device, and click Next.

Create a Certificate Profile 

  1. Select Create a new certificate profile.
  2. Enter the name of the profile, and click Next.

Create an Author Certificate

  1. Select Create a new author certificate, and click Next.
  2. Enter the author and password information.
  3. (Optional) Check Apply the same password for the distributor certificate, and click Next.
  4. Log in to your Samsung account.
  5. When the Congratulations! window is displayed, author certificate generation is complete. Click Next to finish.

Create a Distributor Certificate 

  1. Select Create a new distributor certificate, and click Next.
  2. Enter the privilege level, password, and device unique ID (DUID) information, and click Next.
  3. Verify that the DUIDs of connected devices are in the Add Individual DUIDs list.
  4. When the Congratulations! window is displayed, distributor certificate generation is complete. Click Finish.     
  5. When the Create Certificate Profile popup window is displayed, profile generation is complete. Click OK.
  6. In the Certification Manager, review the certificate profile name and certificate information. Click Close.
  7. In the Connection Explorer, right-click your Gear device and select Permit to install applications.
    This transfers the certificate info to the device (from device-profile.xml to the /home/developer folder of device).
  8. When the upload success popup is displayed, click OK.

Through Project Explorer 

  1. In Tizen Studio, go to the Project Explorer.
  2. Right click on your project, and select Run as > Tizen Web Application.

Your application will be installed on your Gear device.

Through a Terminal 

Use the following command:

$ sdb install <pkg-file>

Run the App on the Emulator 

Tizen Studio provides an emulator to run your Gear app.

Create an Emulator Instance 

  1. In the Connection Explorer view, launch the Emulator Manager by clicking the Emulator Manager icon.
    EmulatorManager.PNG
  2. In the Emulator Manager window, click  + Create.
  3. In the Emulator Configuration window:
    1. Select wearable-2.3.2-circle (basic), and click Next.
    2. Select the device definition for the platform version, and click Next.
    3. Specify the emulator properties. You can leave the options set to their default values.
    4. Click Finish.
  4. In the Emulator Manager, launch the emulator instance:
    LaunchEmulatorInstance.PNG
  5. Select the emulator, and click Launch.

The emulator is launched in its own window. You can also see the new emulator instance in the Connection Explorer view. To view the emulator folder structure, click the arrow next to the emulator instance.

Launch Your App

  1. In the Project Explorer, launch your app:
    LaunchYourApp.PNG
     
  2. Right-click on your project and select Run as > Tizen Web Application.
    Your application will be installed and run in the emulator.

Debug Your Gear App with the Web Inspector Tool  

Debugging a Web application on the target device enables you to understand its flow of control. You can debug your Web Gear application by running it on the target device and debugging its JavaScript code. JavaScript code debugging uses the Web Inspector tool.

  1. Connect the target device to your computer.
  2. Open the Debug Configurations window by doing either of the following:
    • In the Project Explorer view, right-click the project and select Debug As > Debug Configurations.
    • In the Tizen Studio menu, go to Run > Debug Configurations.
  3. In the Debug Configurations window, click New Launch Configuration.
  4. Set the timeout using the Timeout value slider.
    The timeout value represents the waiting time for the application launch operation. If you are using a lower configuration system, set a higher timeout value to avoid application launch failure errors.
  5. Enable debugging by clicking Debug.
    Note: You must enable debugging before debugging JavaScript code.
    The Web Inspector tool is displayed in a new Chrome browser window. You can perform the following debugging tasks using the Web Inspector:
    • Inspect styles
    • Inspect the DOM
    • Inspect resources
    • Debug JavaScript code
      Note: The Web Inspector always opens in a new window. Lifecycle synchronization between the application to be debugged and the Web Inspector browser is not supported. Installing Google Chrome on the device is mandatory for the Web Inspector to work. When Google Chrome is installed, the Tizen Studio automatically detects it.
  6. To select the browser path, go to Window > Preferences > Tizen Studio > Web > Chrome.
  7. In the Web Inspector menu, click Sources.

You can set a break point in the code by right-clicking in the marker bar area on the left side of the editor, and selecting Toggle Breakpoint. After the break points have been set, you can view variables, expressions, and the current call stack.

You can control debugging by using the following control buttons:

  ResumeExecutionIcon.PNG Resumes the current execution.
  StepoverIcon.PNG Steps over the highlighted statement.
Executes the current line, and if the line contains a method, executes the method without entering it.
  StepintoIcon.PNG Steps into the highlighted statement.
Executes the current line, and if the line contains a method, steps into the method.
  Steps out of the current method.
  Deactivates all break points.

If the Web app successfully launches on the target device, the JavaScript Log Console View is automatically launched in Tizen Studio. The JavaScript Log Console view displays Web app JavaScript logs.

    • Was this article helpful?