Importieren aus Content Hub und URLdispatcher#

"hooks": {
    "openstore": {
        "apparmor": "openstore/openstore.apparmor",
        "desktop": "openstore/openstore.desktop",
        "urls": "openstore/openstore.url-dispatcher",
        "content-hub": "openstore/openstore-contenthub.json"
    }
},

Im vorherigen Guide haben wir ein wenig darüber erfahren, wie Content Hub funktioniert. In diesem Guide werden wir sehen, wie URLdispatcher funktioniert und wie man mit importierten Daten aus dem Content Hub umgeht.

Verarbeitung von Daten aus dem Content Hub#

../../_images/02ichu.png

OpenStore App aus open-store.io#

Eine der einfachsten Möglichkeiten, eine App zu testen, ist, sich selbst eine Test-Click auf Telegram zu schicken und diese Click-Datei mit dem OpenStore über den Content Hub zu öffnen:

../../_images/03ichu.png

Wenn wir auf die OpenStore App tippen, wird sie geöffnet und fragt, ob wir die Click-Datei installieren möchten. Lassen Sie uns einen Blick in den Main.qml-Code der App <https://github.com/UbuntuOpenStore/openstore-app/blob/master/openstore/Main.qml#L85>``_ werfen, um zu sehen, wie es gemacht wird:

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)
            })
        }
}

Sehen Sie das Connections-Element, das auf den ContentHub abzielt? Wenn es das Signal onImportRequested empfängt, nimmt es die URL der vom Content Hub gesendeten Daten (transfer.items[0].url ist die URL der ersten gesendeten Datei) und öffnet ein PopUp Element, damit der Benutzer die Click installieren kann.

Was ist mit dem URL-Dispatcher?#

Der URL-Dispatcher ist eine Software, ähnlich dem Content Hub, die uns das Leben leichter macht, wenn wir versuchen, die richtige App für ein bestimmtes Protokoll auszuwählen. Zum Beispiel: Wir wollen wahrscheinlich den Webbrowser öffnen, wenn wir auf ein http-Protokoll tippen. Wenn wir auf einen Kartenlink tippen, ist es praktisch, ihn mit uNav zu öffnen oder einen Twitter-Link in der Twitter-App zu öffnen! Wie funktioniert das?

Der URLdispatcher wählt aus, welche App (entsprechend ihrer manifest.json) einen bestimmten Link öffnen soll.

../../_images/05ichu.png

Schauen wir uns an, wie unsere Navigations-App im Inneren aussieht. uNavs Manifest zeigt spezielle Hooks für den URLdispatcher in seinem manifest.json Code:

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 ]

Das bedeutet, dass ein Link, der wie http://map.unav.me/xxxxx,xxxxx aussieht, in uNav geöffnet wird. Und das ist in den Zeilen 2 und 3 definiert, wo es nach dem Protokoll http sucht, gefolgt von map.unav.me.

Außerdem sollte sich ein URI-formatierter geo:xxx,xxx,xxx in uNav öffnen, wie es in Zeile 11 definiert ist.

Und wie verwalten wir die empfangene URL?#

Nachdem der URLdispatcher den Link zur entsprechenden App sendet, müssen wir diese URL oder URI in der Ziel-App behandeln. Mal sehen, wie man das macht:

In the main qml file, we need to add some code to know what to do with the dispatched URL. Let’s check how Linphone app manages this adding a connection to the URI Handler with a Connections element setting UriHandler as a target.

Connections {
    target: UriHandler

    onOpened: {
        console.log('Open from UriHandler')

        if (uris.length > 0) {
            console.log('Incoming call from UriHandler ' + uris[0]);
            showIncomingCall(uris[0]);
        }
    }
}

Wenn die App geöffnet ist, verwaltet dieser Code eine URI in der Form``linphone://sip:xxx@xxx.xx``. Aber wie gehen wir mit dem Link um, wenn die App geschlossen ist?

Wir müssen ein wenig Zusatzcode hinzufügen, der zwei Fälle abdeckt: 1) Wir erhalten eine URL 2) Wir erhalten mehr als eine URL

Let’s check if Qt.application.arguments is not empty and if not, if any argument matches our URI format.

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()
}

Remember to check that %u (to receive 1 URL) or %U (to receive 1 or more URLs) is present under the Exec line in the .desktop file of the app.

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

Was passiert, wenn mehr als eine App den gleichen URL-Typ definiert hat?#

Eine sehr gute Frage. Was passiert, wenn wir auf einen Twitter-Link tippen? Wie wird eine solche URL vom URLdispatcher als Protokoll http oder das Protokoll http://twitter` behandelt?

Was passiert, wenn zwei Apps das gleiche definierte Protokoll haben?

Jetzt ist es an der Zeit, einige Tests durchzuführen und die Ergebnisse im nächsten Guide zu veröffentlichen.