Эта статья посвящена вопросам использования инструментов, входящих в состав Palm® Mojo™ SDK.

При создании приложения для Palm WebOS, используется такая последовательность действий:

WebOS Application Development Workflow

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

  • palm-generate — Для генерирования сцен и приложений
  • palm-package — Для создания инсталляционного пакета, который можно установить на устройство или в эмулятор
  • palm-install —Для установки пакетов на устройство или в эмулятор
  • palm-launch — Для удаленного запуска приложений на устройстве или в эмуляторе
  • worm.jar — Для профилировки приложений

palm-generate

Этот скрипт используется для создания приложений и сцен

Синтаксис вызова утилиты:

palm-generate options

Доступны следующие параметры запуска:

Опция Описание
-f
–overwrite
Перезаписывать существующие файлы
-l
–list
Вывести список доступных шаблонов.
-p {property}
–property={property}
Определяет свойства генерируемого шаблона. Параметр {property} содержит JSON-объект или пары ключ-значение в формате “ключ=значение”. В обоих случаях необходимо заключение значения в кавычки. Кроме того, если в значениях есть пробелы, то эти значения должны быть заключены в одинарные кавычки.
-t {template}
–template={template}
Указывает на необходимость использования шаблона {template}. Если этот параметр не указан, то по умолчанию будет генерироваться новое приложение – шаблон new{{_app}}.
–help Вывод справочной информации.
Примеры использования

Сгенерировать проект с названием “Sample Application” в папке ~/projects/SampleApp

palm-generate -p "title=Sample Application" ~/projects/SampleApp

Создать новое приложение и указать название, уникальный идентификатор и версию

palm-generate -p "{title:'Super Application', id:com.mystuff.superapp, version:'1.1'}" ~/projects/SuperApp

Добавить новую сцену с названием First в приложение HelloWorld

palm-generate -t new_scene -p "name=First" ~/projects/HelloWorld

palm-package

Утилита-упаковщик, которая создает .ipkg файл, который, в свою очередь, может быть установлен в эмулятор или на устройство.

Синтаксис вызова:

palm-package [options ] application-directory

Доступные опции:

Опция Описание
-o {directory}
–outdir={directory}
Каталог, в котором должен быть создан .ipkg файл. Если эта опция не задана, то установочный пакет приложения будет создан в текущем каталоге.
–exclude={pattern} Исключает из обработки файлы, которые подпадают под описание {pattern}. Шаблон {pattern} может также содержать символы * и ?. Значение шаблона чувствительно к регистру если не указана опция –ignore-case.
-X {pattern_file}
–exclude-from={pattern_file}
Исключает из обработки файлы, названия которых совпадают с любым из шаблонов, указанных в параметре {pattern_file}. В файле {pattern_file} указываются шаблоны названий файлов, по одному в каждой строке. Шаблоны названий файлов могут содержать символы * и ?. Значение шаблона чувствительно к регистру если не указана опция –ignore-case.
–ignore-case Указыват что регистр символов в названиях файлов должен быть проигнорирован.
–no-exclude-eclipse По умолчанию, файлы проектов Eclipse исключаются из обработки. Если нужно их включить в инсталляционный пакет, используется эта опция.
–no-exclude-hidden По умолчанию, скрытые файлы исключаются из обработки. Если нужно их включить в инсталляционный пакет, используется эта опция.
–no-exclude-vcs По умолчанию, файлы и каталоги, необходимые для работы систем контроля версий, исключаются из обработки. Если нужно их включить в инсталляционный пакет, используется эта опция.
–help Выводит справочную информацию.
Примеры использования

Создать приложение HelloWorld

palm-package ~/projects/HelloWorld

Создать приложение Sample но исключить из дистрибутива текстовые файлы и папку docs.

palm-package --exclude="*.txt" --exclude="docs" ~/projects/Sample

palm-install

Эта утилита устанавливает приложения в эмулятор или на устройство. Нельзя установить приложение если устройство находится в режиме синхронизации (Media Sync mode). Если приложение устанавливается на устройство, то устройство должно находиться в режиме Developer Mode (см. ниже)

Синтаксис вызова:

palm-install [options] [package]

Доступные опции:

Опция Описание
-d {device}
–device={device}
Указывает устройство, на которое должна производиться установка приложения:

  • tcp – эмулятор.
  • usb – устроство.
    Если эта опция не указана, то программа будет установлена на первое найденное устройство.
-l
–list
Выдает список приложений, установленных на устройстве.
-r {application}–remove {application} Удаляет приложение, уникальный идентификатор которого соответствует параметру {application}.
–help Выводит справочную информацию.
Примеры использования

Установить приложение

palm-install ~/projects/packages/com.example.app_1.0_all.ipk

Удалить приложение

palm-install -r com.example.app

Вывести список приложение в эмуляторе

palm-install -d tcp -l

palm-launch

Запускает приложение в эмуляторе или на устройстве

Синтаксис вызова:

palm-launch [options] {application}

{application} – уникальный идентификатор приложения

Доступные опции:

Опция Описание
-c
–close
Закрывает приложение вместо запуска.
-d {device}
–device={device}
Устройство:

  • tcp – эмулятор.
  • usb – устроство.
    Если эта опция не указана, то программа будет установлена на первое найденное устройство.
-f
–relaunch
Перезапускает приложение.
-i Запускает приложение в Inspector.
-l
–list
Выводит список установленных приложений.
-p {parameters}–params={parameters} Указывает параметры запуска. Значение {parameters} содержит JSON-объект или пары ключ-значение в формате “ключ=значение”. В обоих случаях необходимо заключать все в двойные кавычки.
–help Выводит справочную информацию.
Примеры использования

Запустить приложение

palm-launch com.example.app

Запустить приложение в режиме отладки

palm-launch -p "{mojoConfig:true, debuggingEnabled:true}" com.example.app

Включение Developer Mode

  1. В Card view или в Launcher ввести текст:
    upupdowndownleftrightleftrightbastart
  2. Нажать на иконку Developer Mode Enabler.
  3. В приложении установить значение слайдера Developer Mode в позицию On.
  4. Нажать Reset the Device.

После перезагрузки режим Developer Mode будет включен.

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

Leave a Reply

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

У.

Учимся работать с GPS в Palm WebOS

GPS нынче – одна из часто востребованных функций в мобильных устройствах и поэтому в этот раз будем рассматривать вопросы использования GPS в приложениях для Palm WebOS.

Итак… Работа с GPS в WebOS осуществляется посредством вызова системного сервиса palm://com.palm.location. Вызов сревиса происходит с помощью метода serviceRequest() контроллера приложения. Тоесть в коде это выглядит как-то так:

this.controller.serviceRequest('palm://com.palm.location', ...);

В WebOS сервис, осуществляющий взаимодействие с GPS-приемником имеет три публичных метода:

  • getCurrentPosition – Синхронный метод получения актуальных GPS-координат
  • startTracking – Подписка на изменение GPS-координат
  • getReverseLocation – Получение информации по указанным координатам (геокодер)

Рассмотрим каждый метод по очереди.

getCurrentPosition

В документации в качестве примера использования этого метода значится вот такой кусок кода:

this.controller.serviceRequest('palm://com.palm.location', {
   method:"getCurrentPosition",
   parameters:{},
   onSuccess:{},
   onFailure:{}
   }
});

На самом же деле этот кусок кода описывает вызов метода только формально и вводит в заблуждение. Первое, с чем приходится столкнутьс, это доступ к полученным координатам. Если писать что-то внутри операторных скобок, которые указаны в качестве значения параметра onSuccess, то получим ошибку. Правильным же способом является указание метода-обработчика для onSuccess и onFailure.

  • onSuccess – метод, который будет вызван в случае если запрос отработал успешно
  • onFailure – метод, который будет вызван в случае если запрос завершился с ошибкой

Тоесть минимально рабочим примером, который позволит нам получить координаты будет следующий код:

FirstAssistant.prototype.handleCoordButton = function(event)
{
	this.controller.serviceRequest(
		'palm://com.palm.location', 
		{
   			method:"getCurrentPosition",
   			parameters: {},
   			onSuccess: this.getCooSuccessResponseHandler.bind(this),
   			onFailure: {}
   		});
}

FirstAssistant.prototype.getCooSuccessResponseHandler = function(event){
	this.controller.showAlertDialog({
    title: $L("Location"),
    message: 'Latitude: '+event.latitude+'\nLongitude: '+event.longitude,
    choices:
    	[
			{label:$L("OK"), value:"ok"}    
    	]
    });
}

Как видно в примере, мы указываем обработчик только для onSuccess. Для onFailure это делается аналогичным образом. В обработчике onFailure модно также узнать код ошибки. Код ошибки содержится в свойстве errorCode объекта, передаваемого в качестве параметра обработчика. errorCode – это целочисленное свойство, которое может принимать одно из следующих значений:

  • 0: Нет ошибки
  • 1: Таймаут
  • 2: Координаты недоступны
  • 3: Неизвестная ошибка
  • 5: Выключен сервис GPS
  • 6: Доступ запрещен – Пользователь не принял условия лицензионного соглашения на использование сервиса GPS.
  • 7: У приложения уже есть сообщение в очереди
  • 8: Приложение временно в черном списке.

Если вы тестируете свое приложение на эмуляторе, то скорее всего сразу получите ошибку с кодом 6. Для того чтобы это исправить, надо в Launcher’е выбрать пункт Location Services и там согласиться с условиями лицензионного соглашения на использование геолокационных сервисов.
Кроме, собственно, широты и долготы, в обработчике получения координат можно узнать еще кучу полезной информации. Более детально о списке доступны параметров можно узнать здесь.

startTracking

Подписка на получение координат от сервиса. Очень полезная штука. Позволяет в асинхронном режиме получать новые значения координат. Пример из документации опять говорит нам вот что:

this.controller.serviceRequest('palm://com.palm.location', {
   method:"startTracking",
   parameters:{},
   onSuccess:{},
   onFailure:{}
   }
});

И здесь, опять же, снова нехватает нормальной демонстрации того, как надо указывать обработчики для onSuccess и onFailure.
А на самом деле все должно быть как-то так:

first-scene.html

<div id="main" class="palm-hasheader">
     <div class="palm-header">GPS Test</div>
     <div id="coordinates" class="palm-body-text">0</div>
</div>

first-assistant.js

...
FirstAssistant.prototype.setup = function() {
     this.controller.get("coordinates").update('Unknown');
     
     this.points = 0;
     this.trackingHandle = this.controller.serviceRequest(
     	'palm://com.palm.location', 
     	{
			method:"startTracking",
			parameters: {"subscribe":true},
			onSuccess:  this.trackingSuccessResponseHandler.bind(this),
			onFailure:  this.trackingFailedResponseHandler.bind(this)
		});
}

FirstAssistant.prototype.cleanup = function(event) {
	this.trackingHandle.cancel();
}
...
FirstAssistant.prototype.trackingSuccessResponseHandler = function(event){
	this.points++;
	this.controller.get("coordinates").update(
		'Coordinates:<ul>'+ 
		'<li>Count: ' + this.points + '</li>'+
		'<li>Latitude: ' + event.latitude + '</li>'+
		'<li>Longitude: ' + event.longitude+'</li>'+
		'</ul>');
}

FirstAssistant.prototype.trackingFailedResponseHandler = function(event){
	this.controller.get("coordinates").update(
		'Failed to retrieve coordinates: ' + event.errorCode);
}
...

Что мы тут сделали:

  • Создали текстовое поле с идентификатором coordinates
  • В конструкторе подписались на событие получения GPS-координат
  • Когда координаты приходят, показываем их в текстовом поле вместе со счетчиком получений
  • Если происходит ошибка, то показываем сообщение об ошибке и код ошибки
  • В деструкторе отписываемся от события вызвав метод this.trackingHandle.cancel()

Обо всех остальных параметрах, получаемых в onSuccess можно прочитать здесь.

getReverseLocation

Пример кода в документации следующий:

this.controller.serviceRequest('palm://com.palm.location', {
   method:"getReverseLocation",
   parameters:{},
   onSuccess:{},
   onFailure:{}
   }
});

В качестве параметров метода могут фигурировать latitude и longitude – широта и долгота.

В onSuccess в объекте-параметре метода свойство address будет содержать адрес, полученный по указанным координатам.

В onFailure коды ошибки могут быть такими:

  • 0: Нет ошибок
  • 6: Доступ запрещен
  • 7: У приложения есть сообщения в очереди
  • 8: Приложение временно в черном списке

Более подробно о методе getReverseLocation можно узнать здесь.

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

О.

Обработка параметров запуска приложения в Palm WebOS

В прошлый раз я рассказывал о том, как выполнить телефонный звонок из приложения в Palm WebOS. Все манипуляции выполнялись с помощью сервиса Application Manager, который запускал приложение дозвона с параметрами.

В этот раз мы более детально рассмотрим возможность запуска приложений в Palm WebOS, а также механизмы, позволяющие обработать параметры, которые были переданы приложению при запуске.Итак, наша цель – создать приложение, корректно обрабатывающее параметры запуска.

Чтобы оно заработало, нам эти параметры надо как-то этому приложению передать. И вот для этих целей мы напишем утилиту-launcher, которая с помощью Application Manager будет запускать наше приложение и передавать в параметрах ему все что нужно.

Пишем Launcher

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

app/views/main/main-scene.html

<div>
<div class="palm-group">
  <div class="palm-group-title">Application</div>
  <div clas="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">Name</div>
          <div id="AppTextBox" 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">Action</div>
          <div id="ActionTextBox" 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">Parameter</div>
          <div id="ParamTextBox" x-mojo-element="TextField"></div>
        </div>
      </div>
    </div>
  </div>
</div>
<div id="LaunchButton" x-mojo-element="Button"></div>
<div id="ExitButton" x-mojo-element="Button"></div>
</div>

app/assistants/main-assistant.js

function MainAssistant() {
}

MainAssistant.prototype.setup = function() {
        this.controller.setupWidget('AppTextBox',
        {
            modelProperty:  'originalValue',
            textCase:       Mojo.Widget.steModeLowerCase,
            focus:          true
        },
        this.appModel =
        {
            originalValue : 'com.mobiledeveloper.appparameters'
        });
        this.controller.setupWidget('ActionTextBox',
        {
            modelProperty:  'originalValue',
            textCase:       Mojo.Widget.steModeLowerCase,
            focus:          false
        },
        this.actionModel =
        {
            originalValue : 'add'
        });
    this.controller.setupWidget('ParamTextBox',
        {
            modelProperty:  'originalValue',
            textCase:       Mojo.Widget.steModeLowerCase,
            focus:          false
        },
        this.paramModel =
        {
            originalValue : 123.45
        });

        this.controller.setupWidget("LaunchButton", {}, {label:"Launch"});
        this.controller.setupWidget("ExitButton", {}, {label:"Exit"});

        Mojo.Event.listen(this.controller.get("LaunchButton"),
            Mojo.Event.tap, this.handleLaunchButton.bind(this));
        Mojo.Event.listen(this.controller.get("ExitButton"),
            Mojo.Event.tap, this.handleExitButton.bind(this));
}

MainAssistant.prototype.cleanup = function(event) {
        Mojo.Event.stopListening(this.controller.get("LaunchButton"),
            Mojo.Event.tap, this.handleLaunchButton.bind(this));
        Mojo.Event.stopListening(this.controller.get("ExitButton"),
            Mojo.Event.tap, this.handleExitButton.bind(this));
}

MainAssistant.prototype.handleLaunchButton = function(event) {
        try
        {
            this.controller.serviceRequest('palm://com.palm.applicationManager',
            {
                method:'launch',
                parameters:
                {
                        id: this.appModel.originalValue,
                        params:
                        {
                            action: this.actionModel.originalValue,
                            param: this.paramModel.originalValue
                        }
                }
            });
        }
        catch(e)
        {
            this.controller.showAlertDialog({
                onChoose: function(value){},
                title: 'Error',
                message: e,
                choices: [{label:'OK'}]
        });
    }
}

MainAssistant.prototype.handleExitButton = function(event) {
    this.controller.stageController.getAppController().closeAllStages();
    window.close();
}

Сцена содержит три поля ввода:

  • В первом – вводим уникальный идентификатор приложения, которое будем запускать
  • Во втором – параметр action, который будет передан запускаемому приложению
  • В третьем – параметр param, который будет передан запускаемому приложению

При запуске Launcher выглядит так:

WebOS Application Launcher (sample)

Рассмотрим более детально, как же происходит запуск стороннего приложения:

  • Мы вызываем Application Manager с помощью метода serviceRequest() объекта-контроллера
  • Методу serviceRequest мы скармливаем название сервиса и JSON-объект с параметрами вызова сервиса
  • В параметрах вызова сервиса указываем, что вызывается метод launch, а также указывается JSON-объект , который будет передан в качестве параметра методу launch.
  • Объект, передаваемый методу launch содержит поле id, а котором указан идентификатор вызываемого приложения, а также поле params, содержащее JSON-объект, передаваемый в качестве параметра запускаемому приложению.

И вот, c launcher’ом мы закончили. Теперь приступим к примеру, демонстрирующему обработку параметров запуска.

Учимся обрабатывать параметры запуска приложения

Для начала создадим новое приложение и в нем сцены с названием first и add.

Если приложение должно обрабатывать параметры запуска, это значит что нам необходимо создать свой Application Assistant – класс, обеспечивающий логику работы приложения. Если мы создаем свой Application Assistant, то и создание GUI мы тоже должны будем прописывать руками. По умолчанию генератор проектов создает проект, содержащий главное окно. В нашем же случае все окна мы будем создавать руками (в коде). Для того, чтобы создавать окна в коде и избавиться от автоматически создаваемого окна, нам надо править файл appinfo.json. В нем необходимо указать параметр noWindow равным true.

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

Указание значения noWindow является очень важным шагом, т.к. без этого свойства в приложении будут создаваться два окна и при запуске это будет выглядеть очень странно, что может в последствии стать причиной отказа в приеме приложения в Palm’овский e-commerce для приложений.

По умолчанию, кодогенератор для проектов создает код для Stage Assistant. Нам он теперь не понадобится и поэтому файл app/assistants/stage-assistant.js можно смело удалять.

Теперь поработаем над созданными ранее сценами:

app/views/first/first-scene.html

<div id="main" class="palm-hasheader">
  <div class="palm-header center" id="main-hdr">Main Scene</div>
</div>
<div x-mojo-element="Button" id="AddSceneButton"></div>
<div x-mojo-element="Button" id="ExitButton"></div>

app/assistants/first-assistant.js

function FirstAssistant() {
}

FirstAssistant.prototype.setup = function() {
    this.controller.setupWidget("AddSceneButton", {}, {label:"Add"});
    this.controller.setupWidget("ExitButton", {}, {label:"Exit"});
    Mojo.Event.listen(this.controller.get("AddSceneButton"),
        Mojo.Event.tap, this.handleAddButton.bind(this));
    Mojo.Event.listen(this.controller.get("ExitButton"),
        Mojo.Event.tap, this.handleExitButton.bind(this));
}

FirstAssistant.prototype.cleanup = function(event) {
    Mojo.Event.stopListening(this.controller.get("AddSceneButton"),
        Mojo.Event.tap, this.handleAddButton.bind(this));
    Mojo.Event.stopListening(this.controller.get("ExitButton"),
        Mojo.Event.tap, this.handleExitButton.bind(this));
}

FirstAssistant.prototype.handleAddButton = function(event) {
    this.controller.stageController.pushScene("add");
}

FirstAssistant.prototype.handleExitButton = function(event) {
    this.controller.stageController.getAppController().closeAllStages();
    window.close();
}

Сцена First содержит две кнопки. Первая кнопка запускает сцену Add, а вторая – завершает работу приложения

app/views/add/add-scene.html

<div class="palm-row">
<div class="palm-hasheader">
  <div class="palm-header">Add Scene</div>
</div>
</div>
<div class="palm-row">
  <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
    <div class="title">
      <div id="ParamTextBox" x-mojo-element="TextField"></div>
    </div>
  </div>
</div>

app/assistants/add-assistants.js

function AddAssistant(param) {
    if(param)
    {
        this.initialValue = param;
    }
    else
    {
        this.initialValue = '';
    }
}

AddAssistant.prototype.setup = function() {
    this.controller.setupWidget('ParamTextBox',
    {
        modelProperty: 'originalValue',
        focus: true
    },
    {
        originalValue: this.initialValue
    });
}

Сцена Add содержит текстовое поле, в котором отображается значение аргумента, переданного сцене в качестве параметра.

И вот мы подошли к самому главному – как именно наше приложение должно получать и обрабатывать параметры запуска.

Для того чтобы обработать параметры запуска, в Application Assistant есть метод handleLaunch, у которого есть параметр launchParams – это объект, содержащий параметры запуска. Если приложение было запущено без параметров, то launchParams будет равен null.

app/assistants/app-assistant.js

var AppParameters = {}
AppParameters.StageName = "AppParamaters";

function AppAssistant() {
}

AppAssistant.prototype.handleLaunch = function(launchParams) {
    if(!launchParams)
    {
        Mojo.Log.info('Applicaion was started without parameters');
        this.startDefault();
    }
    else
    {
        Mojo.Log.info('Applicaion was started with parameters');
        switch(launchParams.action)
        {
        case 'add':
            Mojo.Log.info('ADD action');
            this.addSceneParam = launchParams.param;
            this.handleAddAction();
        break;
        }
    }
}

AppAssistant.prototype.startDefault = function() {
    this.stageController = this.controller.getStageController(AppParameters.StageName);
    if (this.stageController)
    {
        this.stageController.popSceneTo('first');
        this.stageController.activate();
    }
    else
    {
        var stageParams =
        {
            name: AppParameters.StageName,
            lightweight: true
        }
        this.controller.createStageWithCallback(stageParams,
            this.pushFirstScene.bind(this));
    }
}

AppAssistant.prototype.handleAddAction = function() {
    this.stageController = this.controller.getStageController(AppParameters.StageName);
    if (this.stageController)
    {
        this.stageController.popSceneTo('first');
        this.stageController.pushScene('add', this.addSceneParam);
        this.stageController.activate();
    }
    else
    {
        var stageParams =
        {
            name: AppParameters.StageName,
            lightweight: true
        }
        var addStageCallback = function(stageController)
        {
            stageController.pushScene('first');
            stageController.pushScene('add', this.addSceneParam);
        }
        this.controller.createStageWithCallback(stageParams,
        addStageCallback.bind(this));
    }
}

AppAssistant.prototype.pushFirstScene = function(stageController) {
    stageController.pushScene('first');
}

В методе handleLaunch мы проверяем значение launchParams и если оно равно null, то вызываем метод startDefault(). Если launchParams не null, то мы выполняем проверку значения поля action и если оно равно add, то вызываем сцену Add.

Метод handleLaunch может быть вызван в двух случаях – при запуске первого экземпляра приложения и для уже запущенного приложения. Об этом надо помнить, когда мы реализуем логику создания сцен в методах startDefault() и handleAddSAction().

В теле метода startDefault() мы получаем объект Stage Controller с именем “AppParameters”. Если полученное значение равно null, то у нас первый запуск приложения. Мы создаем новое окно (stage) с помощью метода createStageWithCallback() и в callback-функции, которая отрабатывает после успешного создания окна, создаем сцену first.

Если же ссылка на Stage Controller, полученная в методе startDefault(), не равна null, то у нас произошел вызов уже запущенного приложения. Мы закрываем все сцены, которые находятся над сценой first. Делаем мы это с помощью метода popSceneTo().

Метод handleAddAction() работает аналогично. Если у нас происходит вызов уже запущенного приложения, то мы закрываем все сцены, находящиеся над сценой first, а затем открываем сцену add и передаем ей в качестве параметра поле param из launchParameters.

Если же мы вызываем приложение первый раз с параметром action=add, то создаем новое окно, в нем создаем сцену first, а затем сцену add и точно так же, скармливаем ей в качестве параметра поле param из launchParameters.

WebOS Launch Application with Parameters

На этом все.

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