在上面的一篇文章中,我们介绍了怎样使用URL disptacher。在这篇文章中,我们来通过一个范例更进一步来了解怎样实现它。


1)创建一个具有URL dispatcher的应用

我们首先打开我们的SDK,然后创建一个最主要的QML template应用。

我们把该应用叫做“MyApp”。

我们首先在“MyApp”的根文件夹加入一个文件叫做“MyApp.url-dispatcher”文件,这里面的内容例如以下:


[
	{
		"protocol": "launchmyapp"
	}
]

这种定义使得不论什么在Qt.openUrlExternally()中具有以“launchmyapp:///”开头的调用,就能够打开该应用。

比方:


Qt.openUrlExternally("launchmyapp:///123");

同一时候,我们改动我们的manifest.json文件例如以下:

{
    "architecture": "all",
    "description": "description of MyApp",
    "framework": "ubuntu-sdk-14.10-dev2",
    "hooks": {
        "MyApp": {
            "apparmor": "MyApp.apparmor",
            "desktop": "MyApp.desktop",
	    "urls": "MyApp.url-dispatcher"
        }
    },
    "maintainer": "XiaoGuo, Liu <xiaoguo.liu@canonical.com>",
    "name": "com.ubuntu.developer.unknown.myapp",
    "title": "MyApp",
    "version": "0.1"
}

注意这里的“urls”项。到这里,我们基本上就行让我们的应用可以被其他的应用调用了。为了可以得到调用应用传来的參数。我们也同一时候改动我们的desktop文件例如以下:

[Desktop Entry]
Name=MyApp
Exec=qmlscene $@ main.qml -- %u
Icon=MyApp.png
Terminal=false
Type=Application
X-Ubuntu-Touch=true

注意这里的"-- %u",这是增加的部分。

为了可以在程序中显示得到的URL信息,我们对程序做了例如以下的改动:



import QtQuick 2.0
import Ubuntu.Components 1.1

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    id:root

    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "com.ubuntu.developer.unknown.myapp"

    Component.onCompleted: {
        mylabel.text = "aaaa";
        console.log( "arg length: " + myarg.arguments.length );

        if ( myarg.defaultArgument === undefined) {
            mylabel.text = "undefined";
        } else {
            mylabel.text = "args: " + myarg.defaultArgument.at(0);
        }

        console.log("argument: " + myarg.defaultArgument.at(0));
        console.log("")
    }

    Arguments {
        id: myarg
        defaultArgument.help: "Expects URL of the media to play."
        defaultArgument.valueNames: ["URL"]
    }

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(50)
    height: units.gu(75)

    Page {
        title: i18n.tr("MyApp")

        Column {
            spacing: units.gu(1)
            anchors {
                margins: units.gu(2)
                fill: parent
            }

            Row {
                spacing: units.gu(2)

                Label {
                    id: mylabel
                    objectName: "label"

                    text: i18n.tr("Received parameters: ")
                }

                Label {
                    id: label
                    objectName: "label"

                    text: i18n.tr("")
                }

                Connections {
                    target: UriHandler
                    onOpened: {
                        // root.applicationName = "good"
                        mylabel.text = "dddddd";

                        var para = "";
                        for (var i = 0; i < uris.length; ++i) {
                            // application.parseArgument(uris[i])
                            console.log( uris[i] );
                            para +=  uris[i];
                        }

                        label.text = para;
                    }
                }
            }
        }
    }

}

注意这里的“UriHandler”部分,当应用在执行时,url dispatcher被调用时。该部分代码会被执行。

当应用没有执行时,我们通过传人的參数从而得到输入的參数值:


    Arguments {
        id: myarg
        defaultArgument.help: "Expects URL of the media to play."
        defaultArgument.valueNames: ["URL"]
    }

整个的代码在例如以下的地址能够找到:

https://code.launchpad.net/~liu-xiao-guo/debiantrial/myapp


2)创建调用应用


这个应用事实上非常easy。

我们直接创建一个主要的QML template应用。同一时候改动我们的main.qml例如以下:


import QtQuick 2.0
import Ubuntu.Components 1.1

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "com.ubuntu.developer.unknown.launchmyapp"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(100)
    height: units.gu(75)

    Page {
        title: i18n.tr("LaunchMyApp")

        Column {
            spacing: units.gu(1)
            anchors {
                margins: units.gu(2)
                fill: parent
            }

            Button {
                objectName: "button"
                width: parent.width

                text: i18n.tr("Launch MyApp")

                onClicked: {
                    Qt.openUrlExternally("launchmyapp:///123");
                }
            }

            Button {
                objectName: "button"
                width: parent.width

                text: i18n.tr("Open MyApp")

                onClicked: {
                    Qt.openUrlExternally("appid://com.ubuntu.developer.unknown.myapp/MyApp/current-user-version");
                }
            }
        }
    }
}

这里我们使用了两种方法来调用我们的“MyApp”。第一种是通过:

 Qt.openUrlExternally("launchmyapp:///123");

这样的方法的优点是能够传人我们须要的參数,并解析,从而对于不同的參数能够得到不同的响应。

第二种方式是通过:

Qt.openUrlExternally("appid://com.ubuntu.developer.unknown.myapp/MyApp/current-user-version");

这样的方法不能解析不论什么的參数,它能够把应用启动起来。我们能够通过例如以下的方法得到应用的一些信息:


执行我们的应用:



我们按下第一个button,假设“MyApp”没有执行时,会显演示样例如以下的在左边的画面。

假设“MyApp”在已经执行的情况下,能够看到例如以下的右边的画面:


   

假设,我们点击应用以下的button的话,能够看到例如以下的画面:



整个项目的源代码在例如以下的地址能够找到:


bzr branch lp:~liu-xiao-guo/debiantrial/launchmyapp