Главная

Руководство: Взаимодействие HTML с Data-скриптом

Взаимодействие HTML с Data-скриптом

MTCHANNEL - это транспорт, позволяющий передавать данные из HTML-шаблона в браузер или data-скрипт.

Как подключить mtchannel:

  • Пропишите внутри тэга <head> в HTML-шаблоне {{ MTCHANNEL|safe }}
  • Шаблонизатор вставит на страницу инлайновый скрипт

После подключения становится доступным объект stmobile.

Методы stmobile:

stmobile.channel.send(fn, [fn_arg], callback)
Запустить функцию из data-скрипта в основном потоке

  • fn - имя функции из data-скрипта
  • fn_arg - опциональный параметр, передаваемые в функцию параметры
  • callback - имя функции, в которую будет передан результат, вернувшийся из функции в data-скрипте

stmobile.channel.sendToThread(fn, [fn_arg], callback)
Запустить функцию из дата-скрипта в отдельном потоке (так можно запустить несколько функций одновременно)

  • fn - имя функции из data-скрипта
  • fn_arg - опциональный параметр, передаваемые в функцию параметры
  • callback - имя функции, в которую будет передан результат, вернувшийся из функции в data-скрипте

stmobile.observer.onViewStatusChanged
Функция, обрабатывающая событие смены статуса активности страницы (по умолчанию undefined)
Если страница сейчас видна пользователю, статус равен 'ViewActive'
Если страница перекрыта другой страницей (отчёт, форма, msgbox), статус равен 'ViewInactive'

Пример: перезагрузка страницы после возврата из формы

<-------------------- HTML-шаблон ------------------->
{{ MTCHANNEL|safe }}
<script type="text/javascript">
    stmobile.observer.onViewStatusChanged = function(status) {
        if (status == 'ViewActive') stmobile.channel.send('reload');
    };
</script>

<-------------------- Дата-скрипт ------------------->
function reload() {
    api.builder.reload();
}

stmobile.launcher.open(uri)
Открыть заданный URI

  • uri - идентификатор ресурса

stmobile.launcher.close([uri])
Открыть заданный URI

  • uri - опциональный параметр, идентификатор ресурса

stmobile.launcher.openUrl(url, [mode])
Открыть заданный URL

  • url - URL ресурса
  • mode - опциональный параметр, режим открытия, по-умолчанию 'default'

stmobile.launcher.openHtml(url, [mode])
Открыть заданный HTML-файл

  • url - путь до файла
  • mode - опциональный параметр, режим открытия, по-умолчанию 'default'

stmobile.launcher.openPdf(path, [mode])
Открыть заданный PDF-файл

  • path - путь до файла
  • mode - опциональный параметр, режим открытия, по-умолчанию 'default'

stmobile.launcher.openImage(path, title, mode)
Открыть изображение

  • path - путь до файла
  • mode - опциональный параметр, режим открытия, по-умолчанию 'default'

Доступные режимы открытия:

  • 'external' - во внешнем браузере
  • 'internal' - в окне МТ
  • 'default' - если не удалось открыть в МТ, то открыть в браузере

Пример:

Мета файл:

{
    "uri": "stmobile://report/routereports/channeltest",
    "type": "report",
    "title": "qsTr(Тест MTChannel)",
    "datascript": {
        "script_file": "channel.js"
    },
    "template": {
        "template_file": "channel.html"
    }
}

Data-скрипт (channel.js):

function init() {}

function data() {}

function test1() {
    api.log.debug("js: test1");
    return "test1_ret";
}

HTML-шаблон (channel.html):

<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src='{{ libPath }}/libs/jquery.js'></script>
    <script type="text/javascript">

        function test1() {
            stmobile.channel.send('test1', '', function(ret) {
                $('#test1').text(ret);
            });
        }

        function launcherOpenTasks() {
            stmobile.launcher.open("stmobile://tasks/hub");
        }

    </script>

    {{ MTCHANNEL|safe }}

    </head>
    <body>
        <button onclick="test1()">test1</button> <span id="test1"> def </span><br><br>
        <button onclick="launcherOpenTasks()">launcherOpenTasks</button><br>
    </body>
</html>

stmobile.launcher.callPhone(number)
Набрать номер телефона

  • number - номер телефона для вызова. Пример: "+74999200000"

Пример:

Мета файл:

{
    "uri": "stmobile://support/techsupport",
    "type": "report",
    "title": "qsTr(Technical Support)",
    "visible": false,
    "datascript": {
        "script_file": "techsupport.js"
    },
    "template": {
        "template_file": "techsupport.html"
    }
}

Data-скрипт (channel.js):

function init() {}
function data() {
    mapper.phoneNumber = '+78005553533';
}

HTML-шаблон (channel.html):

<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src='{{ libPath }}/libs/jquery.js'></script>
    <script type="text/javascript">

        function launcherCallPhone() {
            stmobile.launcher.callPhone({{ phoneNumber }});
        }

    </script>

    {{MTCHANNEL|safe}}

    </head>
    <body>
        <button onclick="launcherCallPhone()">ПОЗВОНИТЬ</button>
        <br>
    </body>
</html>

stmobile.launcher.startIntent(paramString)
Метод служит для запуска и обработки намерений (Intents) Android.

  • paramString - JSON-строка или объект с параметрами:
    data - массив объектов; набор параметров, которые будут подставлены при обработке намерения через нативный метод Intent.putExtra()
    Пример:

    "data": [
      { "name": "latitude",  "type": "float", "value": "51.3234" },
      { "name": "longitude", "type": "float", "value": "24.3234" }
    ]

    В массив data записываются объекты со следующими полями:
    name - имя параметра - ключ в методе Intent.putExtra
    type - тип значения - строка конвертируемая в тип данных Java
    Доступные значения и типы данных Java, в которые они будут сконвертированы:
    int -> Int, float -> Float, long -> Long, string -> String, short -> Short, double -> Double, boolean -> Boolean, fileuri -> Uri-ссылка на файл, сформированная из переданной строки вызовом метода Uri.fromFile, weburi -> ссылка на вебресурс, сформированная методом Uri.parse
    value - значение параметра.

    action - действие, которое нужно выполнить при обработке намерения (см. документацию, раздел Intent Structure).
    Важно! В параметр должно записываться значение строковой константы, а не ее имя с учетом пространства имен Java, то есть, если в документации Android сказано, что для обработки намерения требуется указать action = Intent.ACTION_VIEW, то в документации можно найти строковое значение данной константы - android.intent.action.VIEW. Именно его нужно указывать в качестве значения параметра. Например: "android.intent.action.DIAL"
    actionUrl - если при создании намерения необходимо указать url, значение этой переменной будет передано в конструктор объекта Intent
    chooserTitle - если указан данный параметр, то во время обработки намерения будет показан экран выбора приложений, которые могут его обработать
    actionType - тип действия
    intentPackage - если при создании намерения необходимо передать название пакета, будет вызван метод Intent.setPackage.
    Если значение пустое, то метод Intent.setPackage вызван не будет.
    marketUrl - ссылка на Play-маркет. Если необходимо запустить внешнее приложение, и оно не нашлось в системе, то будет предложено загрузить его из Google Play. Если значение пустое, то поиск производиться не будет, а метод вернет false. Пример: "market://details?id=ru.yandex.yandexnavi"

В большинстве случаев разработчику расширений достаточно получить пример, как вызвать то или иное намерение из JAVA кода, а затем просто подставить необходимые параметры при вызове метода API.

Пример вызова внешнего приложения Yandex Navigator:
Процесс вызова из JAVA-кода описан по ссылке

Intent intent = new Intent("ru.yandex.yandexnavi.action.BUILD_ROUTE_ON_MAP");
intent.setPackage("ru.yandex.yandexnavi");

PackageManager pm = getPackageManager();
List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);

// Проверяем, установлен ли Яндекс.Навигатор
if (infos == null || infos.size() == 0) {
    // Если нет - будем открывать страничку Навигатора в Google Play
    intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("market://details?id=ru.yandex.yandexnavi"));
} else {
    intent.putExtra("lat_from", 55.751802);
    intent.putExtra("lon_from", 37.586684);
    intent.putExtra("lat_to", 55.758192);
    intent.putExtra("lon_to", 37.642817);
}

// Запускаем нужную Activity
startActivity(intent);

Можно провести соответствие параметров вызова метода stmobile.launcher.startIntent. Здесь в конструктор объекта Intent в качестве параметра передается строка action, что в данном примере эквивалентно тому, что параметр action равен "ru.yandex.yandexnavi.action.BUILD_ROUTE_ON_MAP". В указанном выше коде присутствует вызов метода setPackage, соответсвенно, при вызове метода API придется передать параметр intentPackage со значением "ru.yandex.yandexnavi". Также присутствует ссылка на Play Market - значит, параметр marketUrl тоже необходимо установить в значение "market://details?id=ru.yandex.yandexnavi". Для намерения задаются дополнительные данные:

intent.putExtra("lat_from", 55.751802);
intent.putExtra("lon_from", 37.586684);
intent.putExtra("lat_to", 55.758192);
intent.putExtra("lon_to", 37.642817);

Чтобы передать их при вызове метода stmobile.launcher.startIntent, необходимо сформировать параметр data следующим образом:

{   
    "data": [
        { "name": "lat_from", "type": "double", "value": "55.751802" },
        { "name": "lon_from", "type": "double", "value": "37.586684" },
        { "name": "lat_to",   "type": "double", "value": "55.758192" },
        { "name": "lon_to",   "type": "double", "value": "37.642817" }
    ]
}

В итоге, чтобы из расширения вызвать внешнее приложение Yandex Navigator так, чтобы оно построило маршрут от from до to координаты, необходимо осуществить вызов метода startIntent со следующим json-объектом в качестве параметра:

"{
    action: 'ru.yandex.yandexnavi.action.BUILD_ROUTE_ON_MAP',
    data: [
        { name: 'lat_from', type: 'double', value: '55.751802' },
        { name: 'lon_from', type: 'double', value: '37.586684' },
        { name: 'lat_to',   type: 'double', value: '55.758192' },
        { name: 'lon_to',   type: 'double', value: '37.642817' }
    ],
    intentPackage: 'ru.yandex.yandexnavi',
    marketUrl: 'market://details?id=ru.yandex.yandexnavi'
}"

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

Пример вызова внешнего приложения Google Maps:
Процесс вызова из JAVA-кода описан по ссылке
По аналогии с предыдущим примером вызов метода будет осуществляться со следующими параметрами:

{
    action:        'android.intent.action.VIEW',
    data:          [],
    actionUrl:     ''
    intentPackage: 'com.google.android.apps.maps',
    marketUrl:     'market://details?id=com.google.android.apps.maps'
}

Пример вызова внешнего приложения CityGuide:
Процесс вызова из JAVA-кода доступен по запросу разработчикам
По аналогии с предыдущим примером вызов метода будет осуществляться со следующими параметрами:

{
    action: 'android.intent.action.SEND',
    data: [
        { 
            name:  'android.intent.extra.TEXT',
            type:  'string',
            value: 'cgcmd delroute setroute 1 55.344323 24.324543'
        }
    ],
    intentPackage: 'cityguide.probki.net',
    marketUrl: 'market://details?id=cityguide.probki.net',
    actionType: 'vnd.android.cursor.item/vnd.net.probki.cityguide.cmd'
}

Больше примеров использования намерений можно также найти здесь