195 lines
18 KiB
Markdown
195 lines
18 KiB
Markdown
# Введение
|
||
|
||
Начиная с версии 4.0, AIO Launcher поддерживает скрипты, а точнее специальные виджеты, написанные на скриптовом языке [Lua](https://en.wikipedia.org/wiki/Lua_(programming_language)). Такие виджеты следует размещать в каталоге `/sdcard/Android/data/ru.execbit.aiolauncher/files/`. Затем их можно добавить на экран используя раздел настроек "Скрипты" или с помощью бокового меню.
|
||
|
||
Возможности скриптов ограничены, но с их помощью можно практически безгранично расширять функциональность приложения (посмотрите примеры в этом репозитории).
|
||
|
||
# Функции (колбеки) жизненного цикла
|
||
|
||
Работа любого скрипта-виджета начинается с одной из трех описанных функций. Именно внутри них следует выполнять основную работу и выводить на экран данные.
|
||
|
||
* `on_resume()` - вызывается при каждом возврате на рабочий стол;
|
||
* `on_alarm()` - вызывается при возврате на рабочий стол при условии, что с прошлого вызова прошло больше 30 минут;
|
||
* `on_tick()` - вызывается каждую секунду пока лаунчер находится на экране.
|
||
|
||
Для большинства сетевых скриптов (загрузка и показ значений) следует использовать `on_alarm()`. Использование других функций может привести к блокировке вашего IP.
|
||
|
||
# Функции показа данных
|
||
|
||
* `ui:show_text(string)` - выводит в виджет обычный текст; повторный вызов стирает предыдущий текст;
|
||
* `ui:show_lines(table, [table])` - выводит список строк с отправителем (на манер почтового виджета), второй аргумент (необязательный) - соответствующие им отправители (форматирование в стиле почтового виджета);
|
||
* `ui:show_buttons(names, [colors])` - выводит список кнопок, первый аргумент - таблица строк, второй опциональный аргумент, таблица цветов в формате #XXXXXX;
|
||
* `ui:show_progress_bar(text, current_value, max_value)` - показывает прогресс бар;
|
||
* `ui:show_chart(points, [format], [title], [show_grid], [folded_string], [copyright])` - показывает график, points - таблица таблиц координат, format - формат данных (см. ниже), title - название графика, show\_grid - флага показа сетки, folded\_string - строка для свернутого состояния (иначе будет показано название), copyright - строка, отображаемая в правом нижнем углу;
|
||
* `ui:show_toast(string)` - показывает информационное сообщение в стиле Android;
|
||
* `ui:get_default_title()` - возвращает стандартный заголовок виджета (задается в метаданных `name`);
|
||
* `ui:set_title()` - изменяет заголовок виджета, функцию следует вызывать до функции отображения данных (пустая строка - сброс до стандартного заголовка);
|
||
* `ui:get_primary_text_color()` - возвращает цвет текста темы в формате #XXXXXX;
|
||
* `ui:get_secondary_text_color()` - возвращает цвет вторичного текста (обычно серый) в формате #XXXXXX;
|
||
* `ui:set_folding_flag(boolean)` - устанавливает или снимает флаг свернутого режима виджета, функцию следует вызывать до функций отображения данных;
|
||
|
||
При нажатии на любой элемент интерфейса будет выполнен колбек `on_click(number)`, где number - это порядковый номер элемента. Например, если вы используете `ui:show_buttons` для показа трех кнопок, то при нажатии первой кнопки будет вызван `on_click` с аргументом 1, второй - с аргументов 2, и так далее. Если элемент на экране всего один - аргумент всегда будет равен единице и его можно будет опустить.
|
||
|
||
Функция `ui:show_chart()` в качестве третьего аргумента принимает строку, задающую форматирование значений x и y на экране. Например, строка `x:date y:number` означает, что значения по оси X необходимо отформатировать как даты, а значения по оси Y - как обычное число. Всего существует четыре формата:
|
||
|
||
* `number` - обычное число с разделением групп;
|
||
* `float` - то же самое, но с двумя знаками после запятой;
|
||
* `date` - дата в формате день.месяц;
|
||
* `time` - время в формате часы:минуты.
|
||
|
||
Функции `ui:show_text()` и `ui:show_lines()` поддерживают многие теги HTML. Например:
|
||
|
||
```
|
||
First line<br/>Second line
|
||
<b>Bold Line</b><br/><i>Oblique Line</i>
|
||
<font color="red">Red text</font>
|
||
<span style="background-color: #00FF00">Text on green background</span>
|
||
```
|
||
|
||
# Диалоги
|
||
|
||
* `ui:show_dialog(title, text, [button1_text], [button2_text])` - показать диалог; первый аргумент - заголовок, второй - текст, button1\_text - имя первой кнопки, button2\_text - имя второй кнопки;
|
||
* `ui:show_edit_dialog(title, [text], [default_value])` - показать диалог с полем ввода: title - заголовок, text - подпись, default\_value - стандартное значения поля ввода;
|
||
* `ui:show_checkbox_dialog(title, lines, [index])` - показать диалог с выбором: title - заголовок, lines - таблица строк, index - индекс дефолтового значения;
|
||
|
||
Нажатия на кнопки диалога должны обрабатываться в колбеке `on_dialog_action(number)`, где 1 - это первая кнопка, 2 - вторая, а -1 - нажатие кнопки "закрыть", если никакие кнопки не были указаны. `ui:show_edit_dialog()` возвращает текст в колбек `on_dialog_action(text)`.
|
||
|
||
# Контекстное меню
|
||
|
||
* `ui:prepare_context_menu(table)` - функция подготавливает контекстное меню, которое будет автоматически показано при долгом удержании элемента на экране.
|
||
|
||
В качестве аргумента функция принимает таблицу таблиц с иконками и названиями элементов меню. Например, следующий код подготовит контекстное меню из трех элементов:
|
||
|
||
```
|
||
ui:prepare_context_menu({
|
||
{ "share", "Menu item 1" },
|
||
{ "copy", "Menu item 2" },
|
||
{ "trash", "Menu item 3" },
|
||
})
|
||
```
|
||
|
||
Здесь `share`, `copy` и `trash` - это названия иконок, которое можно узнать на сайте [Fontawesome](https://fontawesome.com/).
|
||
|
||
При нажатии на любой элемент меню будет вызван колбек `function on_context_menu_click(item_idx, menu_idx)`, первый аргумент которого это индекс элемента, для которого было вызвано меню, а второй - индекса элемента самого меню.
|
||
|
||
# Системные функции
|
||
|
||
* `system:open_app(string)` - открывает приложение, имя пакета которого указано в аргументе;
|
||
* `system:open_browser(string)` - открывает указанный URL в браузере или в приложении, умеющем обрабатывать данный тип URL;
|
||
* `system:exec(string)` - выполняет shell-команду;
|
||
* `system:su(string)` - выполняет shell-команду от имени root;
|
||
* `system:get_location()` - возвращает местоположение в таблице с двумя значениями (запрос местоположения НЕ выполняется, используется значение, сохраненное системой ранее);
|
||
* `system:copy_to_clipboard(string)` - копирует строку в буфер обмена;
|
||
* `system:get_from_clipboard()` - возвращает строку из буфера обмена:
|
||
* `system:share_text(string)` - открывает системный диалог "Поделиться";
|
||
* `system:get_lang()` - возвращает выбранный в системе язык;
|
||
|
||
Результат выполнения shell-команды приходит в колбек `on_shell_result(string)`.
|
||
|
||
# Функции управления лаунчером
|
||
|
||
* `aio:do_action(string)` - выполняет действие AIO ([подробнее](https://aiolauncher.app/api.html));
|
||
* `aio:add_widget(string)` - добавляет на экран встроенный виджет, виджет-скрипт или клон существующего виджета;
|
||
* `aio:remove_widget(string)` - удаляет с экрана встроенный виджет или виджет-скрипт (внимание: доп. виджеты тоже будут удалены);
|
||
* `aio:is_widget_added(string)` - проверяет, добавлен ли виджет на экран;
|
||
* `aio:get_args()` - возвращает таблицу аргументов, которые пользователь указал нажав на иконку настроек в режиме редактирования виджета;
|
||
* `aio:set_args(table)` - принудительно устанавливает аргументы скрипта (можно использовать для сохранения настроек скрипта - аргументы не стираются при отключении скрипта);
|
||
* `aio:show_args_dialog()` - показать диалог изменения аргументов;
|
||
|
||
Если в метаданных виджета есть поле `arguments_help`, его значение будет выведено при редактировании аргументов виджета. Если есть поле `arguments_default` - оно будет использовано для получения дефолтовых аргументов.
|
||
|
||
# Сетевые функции
|
||
|
||
* `http:get(url, [id])` - выполняет запрос HTTP GET, id - строка-идентификатор запрос (см. ниже);
|
||
* `http:post(url, body, media_type, [id])` - выполняет запрос HTTP POST;
|
||
* `http:put(url, body, media_type, [id])` - выполняет запрос HTTP;
|
||
* `http:delete(url, [id])` - выполняет запрос HTTP DELETE.
|
||
|
||
Эти функции не возвращают никакого значения, а вместо этого вызывают колбек `on_network_result(string, [code])`. Первый аргумент: тело ответа, второй (опциональный) - код (200, 404 и т.д.).
|
||
|
||
Если в запросе был указан `id`, то функция вместо описанного выше колбека вызовет `on_network_result_$id(string, [code])`. То есть если id равен "server1", то колбек будет иметь вид `on_network_result_server1(string, [code])`.
|
||
|
||
# Функции обработки данных
|
||
|
||
* `ajson:get_value(string, string)` - получает указанное значение из JSON; первый аргумент - JSON-строка, второй - инструкция для получения значения.
|
||
|
||
В отличие от классических парзеров JSON, эта функция предназначена не для парзинга, а именно для извлечения одиночных значений. Например, есть следующий JSON:
|
||
|
||
```
|
||
{
|
||
"type": "success",
|
||
"value": {
|
||
"id": 344,
|
||
"joke": "Aliens DO indeed exist. They just know better than to visit a planet that Chuck Norris is on.",
|
||
"categories": []
|
||
}
|
||
}
|
||
```
|
||
|
||
Необходимо извлечь из него строку "joke". По тексту JSON видно, что эта строка содержится внутри объекта "value", а сам этот объект находится внутри основного объекта JSON. Другими словами чтобы извлечь нужную строку необходимо "открыть" основной объект JSON, затем "открыть" объект "value" и найти в нем строку "joke". В коде это будет выглядеть так:
|
||
|
||
```
|
||
joke = ajson:get_value(result, "object object:value string:joke")
|
||
```
|
||
|
||
При этом полный текст скрипта может выглядеть так:
|
||
|
||
```
|
||
function on_alarm()
|
||
net:get_text("http://api.icndb.com/jokes/random")
|
||
end
|
||
|
||
function on_network_result(result)
|
||
local joke = ajson:get_value(result, "object object:value string:joke")
|
||
aio:show_text(joke)
|
||
end
|
||
```
|
||
|
||
Обратите внимание, что последним элементом строки всегда должна идти инструкция для извлечения примитивных типов данных:
|
||
|
||
* `string:имя`
|
||
* `int:имя`
|
||
* `double:имя`
|
||
* `boolean:имя`
|
||
|
||
Также вместо `object` можно использовать `array` если в JSON находится массив.
|
||
|
||
Подводя итог: ajson хорошо (и очень быстро) работает тогда, когда вам необходимо извлечь одно-два значения. Если же необходимо получить большое количество данных (или все данные) из JSON, то лучше использовать библиотеку json.lua (см. ниже). Она превращает JSON в набор удобных для работы вложенных таблиц Lua.
|
||
|
||
# Другие функции
|
||
|
||
AIO Launcher включает в себя интерпретатор LuaJ 3.0.1 (совместимый с Lua 5.2) со стандартным набором модулей: `bit32`, `coroutine`, `math`, `os`, `string`, `table`.
|
||
|
||
Модули `io` и `package` в целях безопасности исключены из поставки, модуль `os` урезан в функциональности. Доступны только следующие функции: `os.clock()`, `os.date()`, `os.difftime()` и `os.time()`.
|
||
|
||
Стандартный API Lua расширен следующими функциями:
|
||
|
||
* `string:split(delimeter)` - разделяет строку с помощью указанного разделителя и возвращает таблицу;
|
||
* `string:replace(regexp, string)` - заменяет текст, найденный регулярным выражением, на другой текст;
|
||
* `get_index(table, value)` - возвращает индекс элемента таблицы;
|
||
* `get_key(table, value)` - возвращает ключ элемента таблицы;
|
||
* `round(x, n)` - округляет число;
|
||
|
||
В комплект также входят:
|
||
|
||
* `md_colors` - модуль-таблица цветов Material Design (исходник есть в этом репозитории, [справка](https://materialui.co/colors));
|
||
* `url` - модуль с функциями для кодирования/декодирования строки в URL из библиотеки Lua Penlight;
|
||
* [luaDate](https://github.com/Tieske/date) - функции для работы со временем;
|
||
* [json.lua](https://github.com/rxi/json.lua) - парзер JSON;
|
||
* [SLAXDOM](https://github.com/Phrogz/SLAXML) - парзер XML;
|
||
|
||
# Метаданные
|
||
|
||
Чтобы AIO Launcher смог корректно показать информацию о скрипте в каталоге скриптов и корректно вывести заголовок, вы должны добавить в начало скрипта метаданные. Например:
|
||
|
||
```
|
||
-- name = "Covid info"
|
||
-- description = "Cases of illness and death from covid"
|
||
-- data_source = "https://covid19api.com"
|
||
-- arguments_help = "Specify the country code"
|
||
-- arguments_default = "RU"
|
||
-- type = "widget"
|
||
-- author = "Evgeny Zobnin (zobnin@gmail.com)"
|
||
-- version = "1.0"
|
||
```
|