В этот раз речь пойдет об использовании сервиса Connection Manager, который позволяет определить состояние подключения к сети. В WebOS существует возможность узнать состояние подключения к:

  • Bluetoot
  • Wi-Fi
  • WAN

Использовать сервис Connection Manager можно как для одноразового получения состояния сетевых подключений, так и для подписки на уведомление об изменении состояния подключений.Для определения текущего состояния сетевых соединений необходимо вызвать метод serviceRequest() объекта-контроллера, в который передать идентификатор сервиса Connection Manager, а также JSON-объект с параметрами вызова сервиса. Параметры вызова сервиса могут быть такими:

  • method – обязательный параметр. У сервиса Connection Manager есть всего один метод – getstatus.
  • parameters – JSON-объект, который будет передан в качестве параметра методу getstatus. У этого объекта есть одно значимое булевое свойство – subscribe. Если свойство subscribe имеет значение true, то будет выполнена подписка на уведомления об изменении состояния подключений. При каждом изменении состояния будет вызвана наша callback-функция.
  • onSuccess – callback-функция, вызываемая при успешном завершении запроса состояния подключений.
  • onFailure – callback-функция, вызываемая если запрос состояния подключений завершился с ошибкой.

Пример вызова Connection Manager

this.controller.serviceRequest('palm://com.palm.connectionmanager', {
    method: 'getstatus',
    parameters: {subscribe:true},
    onSuccess: this.handleOKResponse.bind(this),
    onFailure: this.handleErrResponse
});

Теперь рассмотрим более детально callback-функции, вызываемые при завершении запроса состояния соединения.

onSuccess

Callback-функция onSuccess принимает в качестве параметра объект, содержащий информацию о состоянии подключений. Этот объект содержит такие поля:

Свойство Тип Описание
errorCode integer Код завершения операции проверки статуса подключения.
errorText string Описание ошибки если errorCode содержит ненулевое значение.
isInternetConnectionAvailable boolean Содержит значение true если есть подключение к Internet.
returnValue boolean true если была выполнена подписка на уведомление об изменении состояния подключений. Может быть получено только первый раз при выполнении подписки.
wifi object Содержит информацию о подключении к Wi-Fi.
btpan object Содержит информацию о подключении к Bluetooth.
wan object Содержит информацию о подключении к WAN.

Теперь посмотрим что можно узнать о подключениях:

Свойства объекта btpan
Свойство Тип Описание
ipAddress string IP-адрес в сети Bluetooth PAN.
panUser string Содержит название клиента сети Bluetooth PAN, подключенного к устройству.
state string Имеет значение “connected” если соединение есть и “disconnected” если соединения нет.
Свойства объекта wifi
Свойство Тип Описание
bssid string Basic service set identifier (BSSID) точки доступа.
ipAddress string IP-адрес в сети Wi-Fi.
ssid string Service set identifier (BSSID) точки доступа.
state string Имеет значение “connected” если соединение есть и “disconnected” если соединения нет.
Свойства объекта wan
Свойство Тип Описание
ipAddress string IP-адрес в сети WAN.
network string Сожет иметь значения: “unknown”, “unusable”, “gprs”, “edge”, “umts”, “hsdpa”, “1x”, or “evdo.”
Внимание: значение “unusable” используется в случае если интерфейс WAN подключен, но данніе не могут быть отправлены или получены по каким-либо причинам.
state string Имеет значение “connected” если соединение есть и “disconnected” если соединения нет.

onFailure

Callback-функция onFailure принимает в качетве параметра объект, содержащий информацию об ошибке. Свойства этого объекта приведены ниже:

Свойство Тип Описание
errorCode string Строка, содержащая код ошибки:

  1. Неизвестная ошибка.
  2. Ошибка подписки на уведомления о состоянии соединения.
errorText string Строка, содержащая описание ошибки.
returnValue boolean false

Пример использования

С теоретической частью мы закончили. Теперь рассмотрим пример.

Создадим новый проект и в нем сцену с названием first.

app/views/first/first-scene.html

<div id="SubscribeButton" x-mojo-element="Button"></div>
<div id="area-to-update"></div>
<div class="palm-inline-error" style="display:none" id="ErrorMessage">
<div class="error-message">Unable to subscribe to Connection Manager's event.</div>
</div>

<div class="palm-group">
  <div class="palm-group-title">Wi-Fi</div>
  <div class="palm-list">
    <div class="palm-row first">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">IP Address</div>
          <div id="WiFiIPTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">BSSID</div>
          <div id="WiFiBSSIDTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">SSID</div>
          <div id="WiFiSSIDTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row last">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">State</div>
          <div id="WiFiStateTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="palm-group">
  <div class="palm-group-title">Bluetooth</div>
  <div class="palm-list">
    <div class="palm-row first">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">IP Address</div>
          <div id="BTPanIPTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">User</div>
          <div id="BTPanUserTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row last">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">State</div>
          <div id="BTPanStateTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="palm-group">
  <div class="palm-group-title">WAN</div>
  <div class="palm-list">
    <div class="palm-row first">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">IP Address</div>
          <div id="WanIPTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">Network</div>
          <div id="WanNetworkTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
    <div class="palm-row last">
      <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
        <div class="title">
          <div class="label">State</div>
          <div id="WanStateTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
  </div>
</div>

app/assistants/first-assistant.js

function FirstAssistant() {
}

FirstAssistant.prototype.setup = function() {
    this.controller.setupWidget('SubscribeButton', {}, {label:'Subscribe'});
    this.controller.setupWidget("BTPanIPTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.btpanIPModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("BTPanUserTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.btpanUserModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("BTPanStateTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.btpanStateModel =
        {
            originalValue: '',
            disabled: true
        });

    this.controller.setupWidget("WiFiIPTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.wifiIPModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("WiFiBSSIDTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.wifiBSSIDModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("WiFiSSIDTextBox",
    {
            modelProperty: 'originalValue'
        },
        this.wifiSSIDModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("WiFiStateTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.wifiStateModel =
        {
            originalValue: '',
            disabled: true
        });

    this.controller.setupWidget("WanIPTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.wanIPModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("WanNetworkTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.wanNetworkModel =
        {
            originalValue: '',
            disabled: true
        });
    this.controller.setupWidget("WanStateTextBox",
        {
            modelProperty: 'originalValue'
        },
        this.wanStateModel =
        {
            originalValue: '',
            disabled: true
        });

    Mojo.Event.listen(this.controller.get('SubscribeButton'),
        Mojo.Event.tap, this.handleSubscribeButton.bind(this));
}

FirstAssistant.prototype.handleSubscribeButton = function(){
    this.controller.serviceRequest('palm://com.palm.connectionmanager', {
        method: 'getstatus',
        parameters: {subscribe:true},
        onSuccess: this.handleOKResponse.bind(this),
        onFailure: this.handleErrResponse
    });
}

FirstAssistant.prototype.handleOKResponse = function(response){
    this.controller.get('ErrorMessage').hide();
    this.controller.get('ErrorMessage').setStyle({visibility:'hidden'});

    this.btpanStateModel.originalValue = response.btpan.state;
    this.btpanIPModel.originalValue = response.btpan.ipAddress;
    this.btpanUserModel.originalValue = response.btpan.panUser;
    this.controller.modelChanged(this.btpanStateModel);
    this.controller.modelChanged(this.btpanIPModel);
    this.controller.modelChanged(this.btpanUserModel);

    this.wifiStateModel.originalValue = response.wifi.state;
    this.wifiIPModel.originalValue = response.wifi.ipAddress;
    this.wifiSSIDModel.originalValue = response.wifi.ssid;
    this.wifiBSSIDModel.originalValue = response.wifi.bssid;
    this.controller.modelChanged(this.wifiStateModel);
    this.controller.modelChanged(this.wifiIPModel);
    this.controller.modelChanged(this.wifiSSIDModel);
    this.controller.modelChanged(this.wifiBSSIDModel);

    this.wanStateModel.originalValue = response.wan.state;
    this.wanIPModel.originalValue = response.wan.ipAddress;
    this.wanNetworkModel.originalValue = response.wan.network;
    this.controller.modelChanged(this.wanStateModel);
    this.controller.modelChanged(this.wanIPModel);
    this.controller.modelChanged(this.wanNetworkModel);
}

FirstAssistant.prototype.handleErrResponse = function(response){
    this.controller.get('ErrorMessage').show();
    this.controller.get('ErrorMessage').setStyle({visibility:'visible'});
}

FirstAssistant.prototype.cleanup = function(event) {
    Mojo.Event.stopListening(this.controller.get("SubscribeButton"),
        Mojo.Event.tap, this.handleSubscribeButton);
}

Сцена содержит кнопку, при нажатии на которую приложение осуществляет подписку на уведомления об изменении состояния сетевых подключений.

Также сцена содержит три группы контролов (текстовых полей), в которых, по приходу уведомления, будет отображаться информация о подключениях.

WebOS Connection Manager Test

В обработчике onSuccess мы получаем значения всех полей из объектов wan, wifi и btpan и отображаем их в соответствующих текстовых полях.

В эмуляторе валидной будет информация только о подключении к Wi-Fi. Другие сетевые подключения на данный момент не доступны под эмулятором.

Скачать исходный код примера.

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

Leave a Reply

Your email address will not be published. Required fields are marked *

Л.

Локализация приложений для Palm WebOS

Чем больше поддерживаемых языков в вашем приложении, тем больше целевая аудитория. Не каждый у нас знает английский, точно так же обстоят дела и во многих других странах, поэтому наличие локализированной версии будет выгодно отличать ваше приложение от приложений конкурентов.

В Palm WebOS локализация происходит достаточно прозрачно. Никаких сверхъестественных знаний не требуется.

Локализируем имя приложения, отображаемое в Launcher

Для того, чтобы в Launcher’е ваше приложение меняло название при смене системных настроек локализации, необходимо скопировать файл appinfo.json в папку с локализированными ресурсами.

Путь для размещения локализированных ресурсов формируется таким образом:

  • В каталоге с проектом создается папка resources
  • В папке resources для каждого языка создается отдельная папка и в ней необходимо размещать файлы локализации, соблюдая структуру каталогов.

Например мы создали приложение следующим образом:

palm-generate -p "id=com.mobiledeveloper.localizableapp" -p "title=Localizable Application" LocalizableApplication
palm-generate -t new_scene -p "name=Main" LocalizaleApplication

Получаем appinfo.json такого вида:

{
 "id": "com.mobiledeveloper.localizableapplication",
 "version": "1.0.0",
 "vendor": "Mobile-Developer.ru",
 "type": "web",
 "main": "index.html",
 "title": "LocalizableApplication",
 "icon": "icon.png"
}

Теперь нам необходимо сделать локализацию. Для этого файл appinfo.json мы копируем в /resources/es_us/appinfo.json и текст файла заменяем на следующий:

{
 "id": "com.mobiledeveloper.localizableapplication",
 "version": "1.0.0",
 "vendor": "Mobile-Developer.ru",
 "type": "web",
 "main": "../../index.html",
 "title": "Translated Application",
 "icon": "../../icon.png"
}

В результате, при смене языка на испанский, получим такое в Launcher’е:
WebOS Localized Application in Launcher

Локализируем HTML-текст сцен

Для того чтобы создать локализированную версию HTML-файла сцены, его также необходимо скопировать в папку с локализированными ресурсами, соблюдая структуру каталогов.

Допустим, у нас был файл /views/main/main-scene.html

<div class="row" style="padding-left: 5px;">
    My<br />text <b>here</b>!
</div>

Для создания испанской локализации нам надо скопировать его в /resources/es_us/views/main/main-scene.html и заменить текст:

<div class="row" style="padding-left: 5px;">
    Your<br />image <b>there</b>!
</div>

После смены языковых настроек в системе, мы увидим измененный текст.

Локализация строк в JavaScript

Все строки, для которых необходима локализация, должны быть помещены в функцию $L():

$L("My text here");

Если по каким-то причинам вы не можете использовать исходную строку в качестве ключа, то значение ключа в словаре с переводом можно указать вручную.

$L("value":"Done", "key": "done_key");

Файл со словарем должен находиться непосредственно в каталоге с локализированніми ресурсами и называться strings.json

{
"My text here": "Mi texto aquí",
"done_key": "Listo",
}

Файл со словарем должен иметь кодировку UTF-8 (без BOM). Если работаете в Eclipse, то, если не указать кодировку для файла и попытаться ввести неанглийские символы и сохранить файл, должно появиться сообщение об ошибке.

Если в строку необходимо подставлять значения переменных, то не надо делать конкатенацию строк, лучше переменные указать в тексте. Это делается потому что для каждого языка положение этих переменных в тексте и последовательность следования переменных может отличаться.

Например английская версия строки может выглядеть так:

"Not enough memory to #{action} the file #{fname}."

…а финская так:

"Liian vähän muistia tiedoston #{fname} #{action}."

Чтобы правильно сделать локализацию подобных строк, нужно использовать метод interpolate():

var data={num:10};
var localizedText = $L("You have #{num} messages").interpolate(data);

или класс Template

var template = new Template($L("You have #{num} messages"));
var localizedText = template.evaluate({num: 10});

Скачать исходный код к статье.

Ч.

Что-то странное творится. В новой прошивке для Palm Pre включена возможность Kill Switch

Kill Switch in WebOSДва дня назад Palm выпустила новую версию Palm WebOS, а несколькими днями ранее официально открыла прием приложений в Palm App Catalog. Все хорошо, если бы не одно «но». Оказывается дурные примеры заразительны и Palm, вслед за Google, включила возможность Kill Switch для App Catalog, с помощью которой они смогут удалять приложения, загруженные из App Catalog, удаленно с устройств пользователей.

Palm reserves the right, at its sole discretion and at any time, to add, remove, disable access to, block, or modify the App Catalog, and to add, remove, disable access to, block, or modify remotely any Applications previously downloaded to your device from the App Catalog.

Ну почему, почему все кому ни попадя хотят ковыряться в софте, установленном на моем устройстве? Я негодую!