Importar desde el centro de contenido y «URLdispatcher»#

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

Hemos visto en la guía anterior un poquito sobre como funciona el centro de contenido. En esta guía veremos como funciona ``URLdispatcher` y como manejar los datos importados desde el centro de contenido.

Manejar datos desde el centro de contenido#

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

Aplicación de OpenStore de open-store.io#

Una de las maneras más fáciles de probar una aplicación es enviarse un «click» de prueba a uno mismo usando Telegram y abriendo ese archivo «click» con OpenStore a través del centro de contenido:

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

Si pulsamos en la aplicación de OpenStore, se abrirá y preguntará si queremos instalar el archivo «click». Echémosle un vistazo al código Main.qml de la aplicación para ver como se hace:

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

¿Ve ese elemento «Connections» que apunta al centro de contenido («ContentHub»)? Cuando recibe la señal «onImportRequested», tomará la url de los datos enviados desde el centro de contenido (transfer.items[0].url es la url de los primeros datos enviados) y abre un elemento PopUp para permitir al usuario instalar el «click».

¿Qué ocurre con el «URLdispatcher»?#

El distribuidor de URL («URL dispatcher») es una pieza de software, similar al centro de contenido, que nos hace la vida más fácil intentando seleccionar la aplicación correcta para un protocolo determinado. Por ejemplo: probablemente queremos abrir el navegador cuando pulsamos sobre un protocolo http. Si pulsamos en un enlace de un mapa es útil abrirlo con uNav, ¡o abrir un enlace de twitter con la aplicación de Twitter! ¿Cómo funciona esto?

El URLdispatcher selecciona que aplicación (de acuerdo con su manifest.json) abrirá un enlace determinado.

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

Veamos como se ve el interior de nuestra aplicación de navegación. El manifiesto de uNav muestra unos ganchos especiales para URLdispatcher (distribuidor de URL) en su código en el manifest.json:

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 ]

Esto significa que un enlace que se parece a http://map.unav.me/xxxxx,xxxxx se abrirá en uNav. Y eso se define en las líneas 2 y 3, donde busca el protocolo http seguido de map.unav.me.

Además, una URI formateada así geo:xxx,xxx debería abrirse en uNav, y se define en la línea 11.

¿Y cómo gestionamos la URL recibida?#

Después de que URLdispatcher envía el enlace a la aplicación correspondiente, necesitamos gestionar esa URL o URI en la aplicación objetivo. Veamos cómo hacer eso:

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

This code will manage an URI in the form linphone://sip:xxx@xxx.xx when the app is opened. But what do we need to do to handle this link when the app is closed?

We need to add a little bit extra code that will cover two cases: 1) We receive one URL 2) We receive more than one 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

¿Qué ocurre si más de una aplicación tiene definido el mismo tipo de URL?#

Una pregunta muy buena. ¿Qué ocurre si pulsamos en un enlace de Twitter? ¿Cómo se maneja tal URL por el URLdispatcher? ¿Cómo protocolo http o cómo el protocolo http://twitter??

¿Qué ocurre si dos aplicaciones tienen definido el mismo protocolo?

Ahora es el momento de hacer algunas pruebas y compartir los resultados en la siguiente guía.