Задача: Bluetooth-чат
- Определение макета приложения
- Определение главного экрана
- Определение экрана выбора сервера
- Определение экрана чата
- Инициализация приложения
- Создание соединения
- Проверка состояния Bluetooth
- Подключение устройств
- Отправка сообщения
Эта задача, основанная на образце BluetoothChat, поставляемом с Tizen SDK, демонстрирует, как вы можете использовать Bluetooth API (в мобильный а также пригодный для носки приложения), чтобы создать чат между 2 устройствами. Для получения дополнительной информации о функциональности примера и создании образца с полным исходным кодом см. BluetoothChat ,
Эта задача состоит из следующих частей:
Этот пример представляет собой полнофункциональное приложение для создания приложения чата.
Определение макета приложения
Пример макета приложения BluetoothChat использует диспетчер шаблонов, основанный на архитектуре MVC (Model-View-Controller), и состоит из 3 экранов: на главном экране отображаются кнопки для создания или присоединения к чату, на экране «Выбор сервера» отображается список доступных серверов, а на экране чата отображаются история разговоров, область ввода и кнопка, позволяющая пользователю писать и отправлять сообщения.
На следующем рисунке показаны основные экраны приложения.
Рисунок: экраны BluetoothChat
Определение главного экрана
- index.html Исходный файл
На главном экране отображаются кнопки выбора. Раздел заголовка экрана определен в элементе <div>, атрибут data-role которого установлен в header. Раздел заголовка определяет заголовок экрана.
<! - Макет главного экрана -> <div id = "start" data-role = "page"> <! - Раздел заголовка -> <div id = "start-header" data-role = "header" data-position = "fixed"> <h1> Bluetooth-чат </ h1> </ div>Фактический раздел содержимого экрана определяется внутри элемента <div>, атрибут data-role которого имеет значение content. Содержит кнопки (в мобильный или же пригодный для носки приложения) для включения соединения Bluetooth и создания или подключения к соединению с сервером. Отображаемые кнопки зависят от того, включен ли адаптер Bluetooth.
<! - Раздел контента -> <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;"> Включить Bluetooth </ div> <div data-role = "button" class = "ui-btn-start" id = "serverButton" style = "display: none;"> Создать сервер </ div> <div data-role = "button" class = "ui-btn-start" id = "clientButton" style = "display: none;"> Присоединиться к серверу </ div> <div id = "start-monit" style = "display: none;"> <p> Ожидание Bluetooth ... </ p> </ div> </ div> </ div> < / DIV>
- app.js Исходный файл
Метод checkPowerState () используется для проверки состояния соединения Bluetooth. Если соединение Bluetooth не включено, на главном экране отображается только кнопка Включить Bluetooth .
checkPowerState: function App_checkPowerState () {this.ui.setContentStartAttributes (this.model.checkPowerState.bind (this.model, this.ui.showPowerOnButton, this.ui.showStartButtons)); }, - app.ui.events.js Исходный файл
События кнопки « Создать сервер» и « Присоединиться к серверу» определены в файле app.ui.events.js. Все события приложения основаны на селекторах jQuery.
$ ('# serverButton'). on ('click', function (event) {app.resetApplicationMode (); app.startServer ();}); $ ('# clientButton'). on ('click', function (event) {app.resetApplicationMode (); app.startClient ();}); - templates / keyboard_page.tpl Исходный файл
Когда пользователь нажимает кнопку « Создать сервер» или « Присоединиться к серверу» , отображается клавиатура, и пользователь может ввести имя сервера или клиента.
<div data-role = "page" id = "клавиатура"> <! - Раздел заголовка -> <div data-role = "header" id = "клавиатура-заголовок" data-position = "fixed"> <h1 > </ h1> </ div> <! - Раздел контента -> <div data-role = "content" id = "клавиатура-контент"> <input type = "text" id = "клавиатура-текст" maxlength = "20" /> </ div> <! - Раздел нижнего колонтитула -> <div data-role = "footer" data-position = "fixed"> <div data-role = "tabbar" data-style = " панель вкладок "> <ul> <li id =" button-ok-button "> <a href="#"> ОК </a> </ li> </ ul> </ div> </ div> </ div >Когда пользователь вводит имя сервера или клиента и нажимает кнопку ОК , метод getApplicationMode () анализирует ввод и отображает выбор сервера или экран чата соответственно.
$ ('# keyboard-ok-button'). on ('click', function (event) {event.preventDefault (); var value = $ ('# keyboard-text'). val (), mode; if (if) value.length! == 0) {app.setUserName (значение); mode = app.getApplicationMode (); if (mode === 'server') {app.setAdapterName ();} иначе if (mode === ' client ') {$ .mobile.changePage (' # choose ');}}});
Определение экрана выбора сервера
- templates / choose_page.tpl Исходный файл
Раздел содержимого экрана «Выберите свой сервер» отображает список (в мобильный или же пригодный для носки приложения) доступных серверов.
<div data-role = "page" id = "Choose"> <! - Раздел заголовка -> <div data-role = "header" id = "Choose-header" data-position = "fixed"> <h1 > Выберите свой сервер </ h1> <div data-role = "progress" data-style = "circle" id = "Discovering"> </ div> </ div> <! - Раздел контента -> <div data -role = "content" id = "choose-content"> <ul data-role = "listview"> </ ul> </ div> </ div>Когда пользователь нажимает на имя сервера, система начинает поиск сервера и пытается подключиться к нему. После подключения система отображает всплывающие окна подтверждения (в мобильный или же пригодный для носки Приложения).
$ ('# choose-content'). on ('tap', 'ul.ui-listview li', function () {app.client.stopServerSearching ($ (this) .attr ('address'));}) ;
Определение экрана чата
- templates / chat_page.tpl Исходный файл
Структура этого шаблона похожа на основной экран. В заголовке отображается текущая роль устройства (сервера или клиента) и его имя.
В области содержимого отображается представление списка с пузырьками сообщений. Расположение пузырьков определяется в файлах шаблонов left_bubble.tpl и right_bubble.tpl.
Нижний колонтитул содержит текстовую область для написания сообщения и кнопку для его отправки.
<div id = "chat" data-role = "page" data-footer-exist = "true"> <! - Раздел заголовка -> <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> <! - Раздел контента -> <div id = "chat-content" data-role = "content"> <ul data-role = "listview"> </ ul> </ div> <! - Раздел нижнего колонтитула -> <div id = "chat-footer" data-role = "footer" data-position = "fixed"> <div id = "ui-textArea"> <div id = "ui-textArea-text"> < textarea id = "text" placeholder = "Ваше сообщение" data-role = "none"> </ textarea> </ div> <div id = "ui-textArea-button"> <a data-role = "button" id = "ui-mySend"> Отправить </a> </ div> </ div> </ div> </ div> - app.ui.js Исходный файл
Метод checkSendButtonState () используется для проверки наличия текста в textArea. Если поле textArea пустое, кнопка Отправить отключена.
checkSendButtonState: function Ui_checkSendButtonState () {if (app.helpers.checkStringLength ($ ('# text'). val (). trim ()) && app.isConnection ()) {this.enableSendButton (); } else {this.disableSendButton (); }},
Инициализация приложения
- config.xml Исходный файл
Требуемые привилегии объявлены в файле config.xml.
<! - Содержимое файла конфигурации -> <widget ...> <! - Другие сведения о конфигурации -> <tizen: privilege name = "http://tizen.org/privilege/application.launch" /> < tizen: имя привилегии = "http://tizen.org/privilege/bluetooth.admin" /> <tizen: имя привилегии = "http://tizen.org/privilege/bluetooth.gap" /> <имя пользователя tizen: привилегия = "http://tizen.org/privilege/bluetooth.spp" /> <! - Прочие сведения о конфигурации -> </ widget>
Создание соединения
Этот раздел основан на элементах, описанных в Обнаружение Bluetooth-устройств а также Подключение и обмен данными с устройством Bluetooth ,
Проверка состояния Bluetooth
- app.server.js Исходный файл
Перед сопряжением устройств необходимо проверить, включен ли Bluetooth. Bluetooth-адаптер по умолчанию извлекается с помощью метода getDefaultAdapter ().
this.adapter = tizen.bluetooth.getDefaultAdapter ();Состояние питания адаптера можно проверить с помощью метода setPowered ().
powerOn: function Model_powerOn (callback) {if (! this.adapter.powered) {try {this.adapter.setPowered (true, function () {setTimeout (function () {callback ();}, 500);}); app.ui.showPowerOnButton (); }} else {callback (); }},
- app.server.js Исходный файл
Одно из устройств должно быть определено для использования в качестве сервера. Это делается с помощью метода registerServer ().
registerServer: function Server_registerServer () {this.model.registerServer (this.adapter, this.serviceUUID, this.registerServerSuccess.bind (this)); },
Подключение устройств
- app.client.model.js Исходный файл
Определив адаптер Bluetooth по умолчанию и настроив сервер, вы можете выбрать запрошенный сервер и связать устройства, используя метод connectToService ().
connectToService: function ClientModel_connectToService (устройство, serviceUUID, successCallback, errorCallback) {this.client.chatServerDevice = device; try {device.connectToServiceByUUID (serviceUUID, successCallback, errorCallback, 'RFCOMM'); }},- Метод connectToService () отправляет эхо-запрос, чтобы убедиться, что сервер отвечает. sendPing: функция ClientModel_sendPing (имя, сокет)
Отправка сообщения
Этот раздел основан на элементах, описанных в Подключение и обмен данными с устройством Bluetooth ,
- app.client.model.js Исходный файл
Перед отправкой сообщения данные сообщения должны быть преобразованы в формат JSON. Затем данные записываются в выбранный сокет с помощью метода writeData ().
sendMessage: function ClientModel_sendMessage (имя, сокет, сообщение, обратный вызов) {var sendTextMsg = [], messageObj, messageObjToString, i, len; имя = encodeURIComponent (имя); сообщение = encodeURIComponent (сообщение); messageObj = {имя: имя, текст: сообщение, ping: false, пока: 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); обратный вызов (сообщение); }}},