Mobile Web Wearable Web

Task: Bluetooth Chat

This task, based on the BluetoothChat sample delivered with the Tizen SDK, demonstrates how you can use the Bluetooth API (in mobile and wearable applications) to create a chat between 2 devices. For more information on the sample functionality and creating the sample with the full source code, see BluetoothChat.

This task consists of the following parts:

This sample is a fully functional application for creating a chat application.

Defining the Application Layout

The BluetoothChat sample application layout uses the template manager based on the MVC (Model-View-Controller) architecture, and consists of 3 screens: the main screen displays buttons for creating or joining a chat, the Choose your server screen displays a list of available servers, and the chat screen displays the conversation history, an input area, and a button, allowing the user to write and send messages.

The following figure shows the main screens of the application.

Figure: BluetoothChat screens

BluetoothChat screens

Defining the Main Screen

  1. index.html Source File
    1. The main screen displays option buttons. The header section of the screen is defined within a <div> element whose data-role attribute is set to header. The header section determines the title of the screen.

      <!--Main screen layout-->
      <div id="start" data-role="page">
         <!--Header section-->
         <div id="start-header" data-role="header" data-position="fixed">
            <h1>Bluetooth chat</h1>
         </div>
    2. The actual content section of the screen is defined within a <div> element whose data-role attribute is set to content. It contains buttons (in mobile or wearable applications) for turning on the Bluetooth connection and either creating or joining a server connection. The buttons displayed depend on whether the Bluetooth adapter is on.

         <!--Content section-->
         <div id="start-content" data-role="content" data-scroll="none">
            <div class="box">
               <div data-role="button" class="ui-btn-start" id="turnOnButton" 
                    style="display: none;">Turn bluetooth on</div>
               <div data-role="button" class="ui-btn-start" id="serverButton" 
                    style="display: none;">Create server</div>
               <div data-role="button" class="ui-btn-start" id="clientButton" 
                    style="display: none;">Join server</div>
               <div id="start-monit" style="display: none;">
                  <p>Waiting for Bluetooth...</p>
               </div>
            </div>
         </div>
      </div>
      
  2. app.js Source File

    The checkPowerState() method is used to check the Bluetooth connection status. If the Bluetooth connection is not on, the main screen only displays the Turn bluetooth on button.

    checkPowerState: function App_checkPowerState() 
    {
       this.ui.setContentStartAttributes(this.model.checkPowerState.bind(this.model,
                                                                         this.ui.showPowerOnButton,
                                                                         this.ui.showStartButtons));
    },
    
  3. app.ui.events.js Source File

    The Create server and Join server button events are defined in the app.ui.events.js file. All the application events are based on jQuery selectors.

    $('#serverButton').on('click', function(event) 
    {
       app.resetApplicationMode();
       app.startServer();
    });
    
    $('#clientButton').on('click', function(event) 
    {
       app.resetApplicationMode();
       app.startClient();
    });
    
  4. templates/keyboard_page.tpl Source File
    1. When the user taps the Create server or Join server button, a keyboard is displayed and the user can enter the server or client name.

      <div data-role="page" id="keyboard">
         <!--Header section-->
         <div data-role="header" id="keyboard-header" data-position="fixed">
            <h1></h1>
         </div>
      
         <!--Content section-->
         <div data-role="content" id="keyboard-content">
            <input type="text" id="keyboard-text" maxlength="20"/>
         </div>
      
         <!--Footer section-->
         <div data-role="footer" data-position="fixed">
            <div data-role="tabbar" data-style="tabbar">
               <ul>
                  <li id="keyboard-ok-button"><a href="#">OK</a></li>
               </ul>
            </div>
         </div>
      </div>
      
    2. When the user enters the server or client name and taps OK, the getApplicationMode() method analyzes the input and displays the server selection or chat screen, respectively.

      $('#keyboard-ok-button').on('click', function(event) 
      {
         event.preventDefault();
         var value = $('#keyboard-text').val(), mode;
         if (value.length !== 0) 
         {
            app.setUserName(value);
            mode = app.getApplicationMode();
            if (mode === 'server') 
            {
               app.setAdapterName();
            } 
            else if (mode === 'client') 
            {
               $.mobile.changePage('#choose');
            }
         }
      });
      

Defining the Choose Your Server Screen

  1. templates/choose_page.tpl Source File
    1. The content section of the Choose your server screen displays a list (in mobile or wearable applications) of available servers.

      <div data-role="page" id="choose">
         <!--Header section-->
         <div data-role="header" id="choose-header" data-position="fixed">
            <h1>Choose your server</h1>
            <div data-role="progress" data-style="circle" id="discovering"></div>
         </div>
      
         <!--Content section-->
         <div data-role="content" id="choose-content">
            <ul data-role="listview"></ul>
         </div>
      </div>
      
    2. When the user taps a server name, the system starts searching for the server and attempts to connect to it. After connecting, the system displays confirmation pop-ups (in mobile or wearable applications).

      $('#choose-content').on('tap', 'ul.ui-listview li', function() 
      {
         app.client.stopServerSearching($(this).attr('address'));
      });
      

Defining the Chat Screen

  1. templates/chat_page.tpl Source File

    The structure of this template is similar to the main screen. The header displays the current role of the device (server or client) and its name.

    The content area displays a list view with message bubbles. The layout of the bubbles is defined in the left_bubble.tpl and right_bubble.tpl template files.

    The footer section contains a textArea for writing a message and a button for sending it.

    <div id="chat" data-role="page" data-footer-exist="true">
       <!--Header section-->
       <div id="chat-header" data-role="header" data-position="fixed">
          <h1><span id="chat-header-type"></span><span id="chat-header-name"></span></h1>
       </div>
    
       <!--Content section-->
       <div id="chat-content" data-role="content">
          <ul data-role="listview"></ul>
       </div>
    
       <!--Footer section-->
       <div id="chat-footer" data-role="footer" data-position="fixed">
          <div id="ui-textArea">
             <div id="ui-textArea-text">
                <textarea id="text" placeholder="Your message" data-role="none"></textarea>
             </div>
             <div id="ui-textArea-button">
                <a data-role="button" id="ui-mySend">Send</a>
             </div>
          </div>
       </div>
    </div>
    
  2. app.ui.js Source File

    The checkSendButtonState() method is used to check whether there is text in the textArea. If the textArea field is empty, the Send button is disabled.

    checkSendButtonState: function Ui_checkSendButtonState() 
    {
       if (app.helpers.checkStringLength($('#text').val().trim()) && app.isConnection()) 
       {
          this.enableSendButton();
       } 
       else 
       {
          this.disableSendButton();
       }
    },
    

Initializing the Application

  1. config.xml Source File

    The required privileges are declared in the config.xml file.

    <!--Configuration file content-->
    <widget ...>
       <!--Other configuration details-->
       <tizen:privilege name="http://tizen.org/privilege/application.launch"/>
       <tizen:privilege name="http://tizen.org/privilege/bluetooth.admin"/>
       <tizen:privilege name="http://tizen.org/privilege/bluetooth.gap"/>
       <tizen:privilege name="http://tizen.org/privilege/bluetooth.spp"/>
       <!--Other configuration details-->
    </widget>

Creating the Connection

This section builds upon the elements described in Discovering Bluetooth Devices and Connecting to and Exchanging Data with a Bluetooth Device.

Checking the Bluetooth Status

  1. app.server.js Source File
    1. Before pairing devices, you must check whether Bluetooth is enabled. The default Bluetooth adapter is retrieved using the getDefaultAdapter() method.

      this.adapter = tizen.bluetooth.getDefaultAdapter();
      
    2. The power status of the adapter can be checked using the setPowered() method.

      powerOn: function Model_powerOn(callback) 
      {
         if (!this.adapter.powered) 
         {
            try 
            {
               this.adapter.setPowered(true, function() 
               {
                  setTimeout(function() {callback();}, 500);
               });
               app.ui.showPowerOnButton();
            }
         } 
         else 
         {
            callback();
         }
      },
      

Registering the Server

  1. app.server.js Source File

    One of the devices must be defined to be used as the server. This is done using the registerServer() method.

    registerServer: function Server_registerServer() 
    {
       this.model.registerServer(this.adapter, this.serviceUUID, this.registerServerSuccess.bind(this));
    },
    

Connecting Devices

  1. app.client.model.js Source File
    1. After defining the default Bluetooth adapter and setting up the server, you can select the requested server and bond the devices using the connectToService() method.

      connectToService: function ClientModel_connectToService(device, serviceUUID, 
                                                              successCallback, errorCallback) 
      {
         this.client.chatServerDevice = device;
         try 
         {
            device.connectToServiceByUUID(serviceUUID, successCallback, errorCallback, 'RFCOMM');
         }
      },
      
    2. The connectToService() method sends a ping to ensure that the server is responding.
      sendPing: function ClientModel_sendPing(name, socket)
      

Sending a Message

This section builds upon the elements described in Connecting to and Exchanging Data with a Bluetooth Device.

  1. app.client.model.js Source File

    Before sending a message, the message data must be stringified to the JSON format. The data is then written to the selected socket using the writeData() method.

    sendMessage: function ClientModel_sendMessage(name, socket, message, callback) 
    {
       var sendTextMsg = [], messageObj, messageObjToString, i, len;
       name = encodeURIComponent(name);
       message = encodeURIComponent(message);
       messageObj = {name: name, text: message, ping: false, bye: false};
       messageObjToString = JSON.stringify(messageObj);
       len = messageObjToString.length;
       for (i = 0; i < len; i += 1) 
       {
          sendTextMsg[i] = messageObjToString.charCodeAt(i);
       }
       try 
       {
          if (socket !== null && socket.state === "OPEN") 
          {
             socket.writeData(sendTextMsg);
             callback(message);
          }
       }
    },
    
Go to top