使用意图系统UI启动应用程序示例
学习如何使用意图从系统UI启动应用程序。
简介
本示例向您展示了如何将意图作为系统UI中启动器的依据。
先决条件:您已经熟悉在“Hello World!”系统UI示例中介绍的概念和主题。此示例使用相同的文件夹结构,并以相同的方式启动。
与“Hello World”示例不同,我们不是直接使用ApplicationObject抽象层启动应用程序,而是使用由软件包注册的launch
意图。这样我们可以在启动器中拥有多个图标,可以启动相同的应用程序,触发应用程序内的不同功能。
注意:任何针对应用程序的意图都会启动它,如果它尚未运行。为了本示例的目的,我们将我们的意图命名为launch
,但应用程序管理器并不赋予此名称特殊含义。
所有launcher
类别的意图图标和名称都在左侧。您可以点击它们的图标将相应的意图请求发送到系统:如果相应的应用程序尚未运行,则会自动启动。在图标上按住并释放将停止ApplicationObject。就像在“Hello World!”示例中一样,右侧的列布局显示了所有运行应用程序的窗口。
应用程序在相应颜色的背景上显示其应用程序名称。此外,它们还显示它们收到多少次launch
类别意图。
实现系统UI
与任何简单的QML应用程序一样,示例的代码从一些导入和一个根级的普通Item开始。唯一的区别是我们还导入了QtApplicationManager
和QtApplicationManager.SystemUI
模块,除了QtQuick
。
import QtQuick 2.12 import QtApplicationManager 2.0 import QtApplicationManager.SystemUI 2.0 Item { width: 800 height: 600
与“Hello World”示例不同,我们现在创建了一个IntentModel来访问所有在launcher
类别的意图。由于此模型默认未排序,我们还根据意图的名称设置排序顺序为降序。
注意:类别的名称可以是您喜欢的任何名称,只要它与应用程序的info.yaml
元数据和应用程序内的相应IntentHandler之间保持一致。
IntentModel { id: intentModel filterFunction: function(i) { return i.categories.contains("launcher") } sortFunction: function(li, ri) { return li.name > ri.name } }
然后,在根Item的左侧有一个列,我们放置了可用意图的图标及其名称。
// Show intent names and icons Column { spacing: 20 Repeater { model: intentModel Column { Image { source: model.icon MouseArea { anchors.fill: parent onPressAndHold: { var app = ApplicationManager.application(model.applicationId) if (app.runState === Am.Running) app.stop() } onClicked: { IntentClient.sendIntentRequest(model.intentId, model.applicationId, {}) } } } Text { font.pixelSize: 20 text: model.name } } } }
我们使用我们的IntentModel,该模型为每个可用意图提供一行。在每行中,我们有
- 一个带有图标URL的
icon
角色 - 一个带有本地化意图名称的
name
角色 - 一个包含意图id的
intentId
角色 - 一个包含处理应用程序id的
applicationId
角色
有关其他可用的角色的信息,请参阅IntentServer QML类型。
接下来,我们在根Item
的右侧放置一个锚定的Column
。该项目与“Hello World!”示例中的完全相同,显示了所有应用程序窗口。
实现该应用程序
我们的启动 Intent 应用程序以文本形式在其彩色背景上显示应用程序名称。
import QtQuick 2.12 import QtApplicationManager.Application 2.0 ApplicationManagerWindow { color: "blue" Text { id: txt property int counter: 0 anchors.centerIn: parent text: ApplicationInterface.name["en"] + "\nLaunch intents received: " + counter } IntentHandler { intentIds: [ "launch" ] onRequestReceived: { txt.counter++ request.sendReply({}) } } }
与“Hello World”示例中的例子之间的唯一区别是,我们通过一个IntentHandler处理额外的传入 launch
意图请求:此 IntentHandler 在本示例中不做任何有用的事情,除了在 Text 对象中增加计数器,以便您可以查看启动意图被接收的次数。有关 IntentClientRequest::sendReply 调用的更多信息,请参阅IntentHandler::requestReceived 文档。
应用程序元数据
info.yaml
文件包含有关包的元数据。它以一些通用文本开始,描述了该文件包含 Qt 应用程序管理器的包元数据。
formatVersion: 1 formatType: am-package ---
然后是包 ID,它唯一地标识了该包。建议遵循反向 DNS 方案,但不是强制性的。这里是“Launch Intents”示例 UI 中的“Blue”包。
id: 'launch-intents.blue'
然后是图标文件名
icon: 'icon.png'
接下来是应用程序在任意多语言中的用户可见名称。对于此示例,我们只提供英语
name: en: 'Blue App'
对于每个包,我们定义一个应用程序,它获得与包本身相同的 id(这不是一个要求,但是一种有用的方法,用于单个应用程序的包)。
applications: - id: launch-intents.blue runtime: 'qml' code: 'main.qml'
每个包至少将注册一个在 launcher
类别中的 launch
意图。在这个情况下,意图的确切名称并不重要,因为系统 UI 将请求所有在 launcher
类别中的意图。意图的名称和图标默认为包的名称和图标,但在这里我们覆盖了名称
intents: - id: launch name: en: 'Launch Blue' categories: [ launcher ]
别名处理
红色应用程序比蓝色和绿色版本做得更多:它使用意图实现已废弃的“别名”机制。
在其 info.yaml
文件中,它定义了在 launcher
类别中的第二个意图,名称为 another-launch
- id: another-launch name: en: 'Launch Another Red' categories: [ launcher ]
为了处理此意图,main.qml
文件中的 IntentHandler 扩展到接受这两个意图
IntentHandler { intentIds: [ "launch", "another-launch" ]
传入意图请求的信号处理器可以根据其 intentId
区分请求的意图,并增加文本字段中正常的 counter
或 anotherCounter
属性。
onRequestReceived: { if (request.intentId === "launch") txt.counter++ else txt.anotherCounter++ request.sendReply({}) }
注意:除了一个IntentHandler处理两个意图之外,也可以使用两个单独的 IntentHandlers 实现此功能,每个处理一个意图。
©2019 瑞典乌克斯佛特 Luxoft AB。所包含的文档贡献的版权属于其各自的所有者。所提供的文档受GNU 自由文档许可证版本 1.3条款许可,由自由软件基金会发布。Qt 及其 respective 标志是芬兰和/或全球其他国家的 The Qt Company Ltd. 的商标。所有其他商标均为其各自所有者的财产。