Files:
The Invoke Target example shows how to handle incoming invocation requests from other applications.
In this example we'll learn how to use the InvokeManager and InvokeRequest classes of the BB10 framework to handle incoming invocation requests from external applications.
All the business logic is encapsulated in the C++ class App, which is exported to the QML files under the name '_app'.
The UI of this sample application consists of one page which displays the startup mode of the application and the values from the incoming request that triggered a start of the application.
LabelLabel { label: qsTr ("startup mode") text: _app.startupMode } LabelLabel { label: qsTr ("source") text: _app.source }
The main page contains a list of labels, where the 'text' property is bound against the associated property of the App object to get automatically updated.
The App object is the mediator between the UI and the bb::system::InvokeManager class. In stores the startup mode and values of incoming invocation requests and makes them available to the UI through properties.
class App : public QObject { Q_OBJECT // The textual representation of the startup mode of the application Q_PROPERTY(QString startupMode READ startupMode NOTIFY requestChanged) // The values of the incoming invocation request Q_PROPERTY(QString source READ source NOTIFY requestChanged) Q_PROPERTY(QString target READ target NOTIFY requestChanged) Q_PROPERTY(QString action READ action NOTIFY requestChanged) Q_PROPERTY(QString mimeType READ mimeType NOTIFY requestChanged) Q_PROPERTY(QString uri READ uri NOTIFY requestChanged) Q_PROPERTY(QString data READ data NOTIFY requestChanged) // The textual representation of the card status Q_PROPERTY(QString status READ status NOTIFY statusChanged) // The title of the application Q_PROPERTY(QString title READ title NOTIFY requestChanged) // Whether the 'Back' button should be visible in the UI Q_PROPERTY(bool backButtonVisible READ backButtonVisible NOTIFY requestChanged) public: App(QObject *parent = 0); public Q_SLOTS: // This method is invoked to notify the invocation system that the action has been done void cardDone(); Q_SIGNALS: // The change notification signal of the properties void requestChanged(); void statusChanged(); private Q_SLOTS: // This slot is called whenever an invocation request is received void handleInvoke(const bb::system::InvokeRequest&); void resized(const bb::system::CardResizeMessage&); void pooled(const bb::system::CardDoneMessage&); private: // The accessor methods of the properties QString startupMode() const; QString source() const; QString target() const; QString action() const; QString mimeType() const; QString uri() const; QString data() const; QString status() const; QString title() const; bool backButtonVisible() const; // The central class to manage invocations bb::system::InvokeManager *m_invokeManager; // The property values QString m_startupMode; QString m_source; QString m_target; QString m_action; QString m_mimeType; QString m_uri; QString m_data; QString m_status; QString m_title; bool m_backButtonVisible; };
Inside the constructor the member variables are initialized with default values and the UI is loaded from the main.qml file.
App::App(QObject *parent) : QObject(parent) , m_invokeManager(new InvokeManager(this)) , m_backButtonVisible(false) { // Listen to incoming invocation requests connect(m_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)), this, SLOT(handleInvoke(const bb::system::InvokeRequest&))); connect(m_invokeManager, SIGNAL(cardResizeRequested(const bb::system::CardResizeMessage&)), this, SLOT(resized(const bb::system::CardResizeMessage&))); connect(m_invokeManager, SIGNAL(cardPooled(const bb::system::CardDoneMessage&)), this, SLOT(pooled(const bb::system::CardDoneMessage&))); // Initialize properties with default values switch (m_invokeManager->startupMode()) { case ApplicationStartupMode::LaunchApplication: m_startupMode = tr("Launch"); break; case ApplicationStartupMode::InvokeApplication: m_startupMode = tr("Invoke"); break; case ApplicationStartupMode::InvokeViewer: m_startupMode = tr("Viewer"); break; case ApplicationStartupMode::InvokeCard: m_startupMode = tr("Card"); break; } m_source = m_target = m_action = m_mimeType = m_uri = m_data = m_status = tr("--"); m_title = tr("InvokeClient"); // Create the UI QmlDocument *qml = QmlDocument::create("asset:///main.qml"); qml->setContextProperty("_app", this); AbstractPane *root = qml->createRootObject<AbstractPane>(); Application::instance()->setScene(root); }
To get informed about incoming invocation requests, the custom slot handleInvoke() is connected against the invoked() signal of the bb::system::InvokeManager object.
void App::handleInvoke(const InvokeRequest& request) { // Copy data from incoming invocation request to properties m_source = QString::fromLatin1("%1 (%2)").arg(request.source().installId()).arg(request.source().groupId()); m_target = request.target(); m_action = request.action(); m_mimeType = request.mimeType(); m_uri = request.uri().toString(); m_data = QString::fromUtf8(request.data()); m_backButtonVisible = false; if (m_target == "com.example.bb10samples.invocation.openimage1") { m_title = tr("Open Image 1"); } else if (m_target == "com.example.bb10samples.invocation.openimage2") { m_title = tr("Open Image 2"); } else if (m_target == "com.example.bb10samples.invocation.card.previewer") { m_title = tr("Previewer"); m_backButtonVisible = true; } else if (m_target == "com.example.bb10samples.invocation.card.composer") { m_title = tr("Composer"); } else if (m_target == "com.example.bb10samples.invocation.card.picker") { m_title = tr("Picker"); } // Signal that the properties have changed emit requestChanged(); }
The values from the passed bb::system::InvokeRequest are copied to the property values and the UI is updated by emitting the change notification signal.
To make the invoketarget application a candidate for invocations, the BB10 system must know about the invocation interface of the application. That is defined inside the bar-descriptor.xml file of the project inside an invoke-target element.
<invoke-target id="com.example.bb10samples.invocation.openimage1"> <invoke-target-name>InvokeTarget Image 1</invoke-target-name> <icon><image>icon.png</image></icon> <type>application</type> <filter> <action>bb.action.OPEN</action> <mime-type>image/png</mime-type> </filter> </invoke-target> <invoke-target id="com.example.bb10samples.invocation.openimage2"> <invoke-target-name>InvokeTarget Image 2</invoke-target-name> <icon><image>icon.png</image></icon> <type>application</type> <filter> <action>bb.action.OPEN</action> <mime-type>image/png</mime-type> </filter> </invoke-target> <invoke-target id="com.example.bb10samples.invocation.card.previewer"> <type>card.previewer</type> <filter> <action>bb.action.OPEN</action> <mime-type>image/png</mime-type> </filter> </invoke-target> <invoke-target id="com.example.bb10samples.invocation.card.composer"> <type>card.composer</type> <filter> <action>bb.action.OPEN</action> <mime-type>image/png</mime-type> </filter> </invoke-target> <invoke-target id="com.example.bb10samples.invocation.card.picker"> <type>card.picker</type> <filter> <action>bb.action.OPEN</action> <mime-type>image/png</mime-type> </filter> </invoke-target>