Импорт данных из Content Hub и URLdispatcher#
"hooks": {
"openstore": {
"apparmor": "openstore/openstore.apparmor",
"desktop": "openstore/openstore.desktop",
"urls": "openstore/openstore.url-dispatcher",
"content-hub": "openstore/openstore-contenthub.json"
}
},
В предыдущем руководстве мы немного узнали о том, как работает Content Hub. В этом руководстве мы увидим, как работает URLdispatcher
и как обрабатывать импортированные данные из Content Hub.
Обработка данных из Content Hub#
Один из самых простых способов тестирования приложения - отправить тестовый click-пакет в свою учётную запись Telegram и открыть этот файл в OpenStore через Content Hub:
Если мы попробуем запустить приложение из OpenStore, то система спросит, хотим ли мы установить click-файл. Давайте посмотрим на файл приложения Main.qml <https://github.com/UbuntuOpenStore/openstore-app/blob/master/openstore/Main.qml#L85> `_, чтобы узнать, как это делается:
Connections {
target: ContentHub
onImportRequested: {
var filePath = String(transfer.items[0].url).replace('file://', '')
print("Should import file", filePath)
var fileName = filePath.split("/").pop();
var popup = PopupUtils.open(installQuestion, root, {fileName: fileName});
popup.accepted.connect(function() {
contentHubInstallInProgress = true;
PlatformIntegration.clickInstaller.installPackage(filePath)
})
}
}
Вы видите элементы Connections, которые относятся к ContentHub? Когда приложение получает сигнал onImportRequested, оно ищет url-адрес в данных, полученных от Content Hub (transfer.items[0].url
- url-адрес первых отправленных пакетов данных) и откроет элемент PopUp
, чтобы пользователь смог установить click-пакет.
Что можно сказать об URLdispatcher?#
Диспетчер URL - это часть программного обеспечения, похожая на Content Hub, которая облегчает нашу жизнь, пытаясь выбрать правильное приложение для определенного протокола. Например: скорее всего, нужно открыть веб-браузер при нажатии на http-ссылку. Ссылку на карту удобнее открыть с помощью uNav, а ссылку на пост Twitter - в приложении Twitter. Как это работает?
URLdispatcher
(Диспетчер URL) выбирает, какое приложение (согласно файлу manifest.json
) откроет определенную ссылку.
Давайте посмотрим, как устроено навигационное приложение. В файле файле manifest.json приложения uNav показаны специальные хуки для `` URLdispatcher`` <https://bazaar.launchpad.net/~unav-devs/unav/trunk/view/head:/manifest.json#L9> `_:
1 [
2 {
3 "protocol": "http",
4 "domain-suffix": "map.unav.me"
5 },
6 {
7 "protocol": "http",
8 "domain-suffix": "unav-go.github.io"
9 },
10 {
11 "protocol": "geo"
12 },
13 {
14 "protocol": "http",
15 "domain-suffix": "www.openstreetmap.org"
16 },
17 {
18 "protocol": "http",
19 "domain-suffix": "www.opencyclemap.org"
20 },
21 {
22 "protocol": "https",
23 "domain-suffix": "maps.google.com"
24 }
25 ]
Это означает, что ссылка в формате http://map.unav.me/xxxxx ,xxxxx будет открыта в приложении uNav. Это определено в строках 2 и 3, где указан протокол http и приложение map.unav.me.
Кроме того, geo: xxx, xxx в формате URI должны открываться в uNav, как это определено в строке 11.
И как мы управляем полученным URL?#
После того, как `` URLdispatcher`` отправит ссылку соответствующему приложению, нам нужно обработать этот URL или URI в целевом приложении. Давайте посмотрим, как это сделать:
В основной файл qml необходимо добавить код, чтобы знать, что делать с отправленным URL-адресом. Давайте проверим, как приложение Linphone управляет этим добавлением подключение к обработчику URI с элементом Connections, задающим в качестве цели UriHandler
.
Connections {
target: UriHandler
onOpened: {
console.log('Open from UriHandler')
if (uris.length > 0) {
console.log('Incoming call from UriHandler ' + uris[0]);
showIncomingCall(uris[0]);
}
}
}
Этот код при открытии приложения будет передаваться URI в формате linphone://sip:xxx@xxx.xx
. Но что нужно сделать, чтобы обработать эту ссылку, когда приложение закрыто?
Нам нужно добавить в исходный файл участок дополнительного кода, который будет описывать два случая: 1) получен один URL 2) Получено более одного URL
Давайте проверим, не пустой ли параметр Qt.application.arguments
, и если нет, то соответствует ли какой-либо аргумент нашему формату URI.
Component.onCompleted: {
//Check if opened the app because we have an incoming call
if (Qt.application.arguments && Qt.application.arguments.length > 0) {
for (var i = 0; i < Qt.application.arguments.length; i++) {
if (Qt.application.arguments[i].match(/^linphone/)) {
console.log("Incoming Call on Closed App")
showIncomingCall(Qt.application.arguments[i]);
}
}
}
//Start timer for Registering Status
checkStatus.start()
}
Не забудьте проверить, что% u (для получения 1 URL-адреса) или% U (для получения 1 или более URL-адресов) присутствует в строке Exec
в файла приложения .desktop .
Tools#
From command line, lomiri-url-dispatcher-dump
command will give you the full list of registered protocol schemes and their corresponding app.
Another usefull tool, but not installed by default on devices is lomiri-url-dispatcher-tools
, it allows you to simulate a call from a third party app. e.g: lomiri-url-dispatcher https://youtu.be/CIX-a-i6B1w
will launch youtube webapp.
To install, it make your partition writable (sudo mount -o rw,remount /
) and install it via sudo apt install lomiri-url-dispatcher-tools
Что произойдет, если для нескольких приложений определен один и тот же тип URL?#
Очень хороший вопрос. Что произойдет, если мы нажмем на ссылку в Twitter? Как такой URL будет обрабатывать `` URLdispatcher``? Она будет воспринята как обычная ссылка `` http`` или как ссылка для приложения`` http: // twitter``?
Что произойдет, если один протокол определен для двух приложений?
Теперь пришло время сделать несколько тестов и обсудить результаты в следующей главе.