Receiving invocation

You can configure your app to receive invocation requests from other apps. To receive an invocation request, your app must support invocation targets. To support invocation targets, you must declare your targets in the bar-descriptor.xml file and handle invocation messages.

Target declaration

For your app to be invoked, you must declare your app as a target in your bar-descriptor.xml file. To declare a target, add the following elements to the bar-descriptor.xml file for each target that the app exposes:

<invoke-target id="com.example.image.view">
  <invoke-target-type>application</invoke-target-type>
  <invoke-target-name>My App Name</invoke-target-name>
  <icon>
    <image>icon.png</image>
  </icon>
</invoke-target>
Attribute Element Description

ID

<invoke-target id>

This attribute uniquely identifies the app as a target. This attribute can also be used by the client apps to perform bound invocation.

Type

<invoke-target-type>

This attribute specifies the type of the target. Apps and cards are supported as types of the target.

Name

<invoke-target-name>

This attribute specifies the name of the target app.

Icon

<icon>

This attribute specifies the icon for the target app.

Receiving invocations

Declaring your app as a target is essential for receiving an invocation request, but to be invoked, your app needs to include code that can receive invocation messages.

Here's how to configure your app to listen for invocation messages:

Not applicable

int main(int argc, char *argv[])
{
    // Other functions in main()
    // ...

    InvokeManager invokeManager;
    
    bool connectResult;
    
    Q_UNUSED(connectResult);
    
    connectResult = QObject::connect(&invokeManager, 
        SIGNAL(invoked(const bb::system::InvokeRequest&)),
        &myApp, SLOT(onInvoke(const bb::system::InvokeRequest&)));
    
    // This is only available in Debug builds
    Q_ASSERT(connectResult);
    
    // Other functions in main()
    // ...

    // Set up your app to listen for invocations
    // Note that you won't receive any
    // messages until you drop it into the exec loop
    return app.exec();
}

// This is the slot function that gets called when the invoked() signal is emitted
void MyApp::onInvoke(const bb::system::InvokeRequest& invoke)
{
    // Handle the invocation
}

Handling launch through invocation

An important thing to consider when you write an app target is how an app is started. Usually, an app starts when the user taps the app icon on the home screen. However, with the invocation framework, the app can also be invoked. So how does an app know whether it was invoked or just started by the user?

Here's how you can determine if your app is invoked or launched:

Not applicable

int main(int argc, char *argv[])
{
    // Other functions in main()
    // ...

    InvokeManager invokeManager;
    
    // If any Q_ASSERT statement(s) indicate that the slot failed to connect to 
    // the signal, make sure you know exactly why this has happened. This is not
    // normal, and will cause your app to stop working!!
    bool connectResult;
    
    // Since the variable is not used in the app, this is added to avoid a 
    // compiler warning
    Q_UNUSED(connectResult);
    
    connectResult = QObject::connect(&invokeManager, 
                    SIGNAL(invoked(const bb::system::InvokeRequest&)),
                    &myApp, 
                    SLOT(onInvoke(const bb::system::InvokeRequest&)));
                    
    // This is only available in Debug builds.
    Q_ASSERT(connectResult);
                    
    // Other functions in main()
    // ...

    switch(invokeManager.startupMode()) {
        case ApplicationStartupMode::LaunchApplication:
            // An app can initialize if it 
            // was started from the home screen
            break;
        case ApplicationStartupMode::InvokeApplication:
            // If the app is invoked, 
            // it must wait until it receives an invoked() signal
            // so that it can determine the UI that it needs to initialize
            break;
        default:
            // What app is it and how did it get here?
            break;
    }

    // Drop the app into the exec loop
    // so that it can start receiving messages
    return app.exec();
}

Target filters

One of the key features of the invocation framework is the ability to discover target apps or cards on a BlackBerry device. Targets are discovered based on the filters they declare in their bar-descriptor.xml file, which describe the kinds of invocation request that a target supports. Target filters let other apps query for your app, making your app a candidate for unbound invocation requests.

Target filters are declared as part of the <invoke-target> element in the bar-descriptor.xml file and consist of the following attributes:

Attribute Description

filter

Describes the criteria for this app to be considered for unbound invocations or invocation queries. This attribute is the containing element for the other attributes that are listed here.

action

Describes the actions that can be performed on the content. This attribute represents the action that the target supports for the types specified in the mime-type attribute. Include one <action> element for each supported action.

mime-type

Describes the type of content. This attribute represents the different types for which the specified actions are supported. You can specify both the type and subtype by using wildcards in a target filter. For example, a filter can specify image/png, image/*, or *. Include one <mime-type> element for each supported MIME type.

uris

Describes the supported URI pattern that must prefix the URI that is provided in the invocation request. This attribute represents the URI prefixes that describe how the target supports the delivery of the data. The URI value may contain the single wildcard character * to indicate that the filter supports any delivery mechanism.

If the target app or a card supports the delivery of the data as part of the message body, then it should include the data://local URI.

exts

Represents the list of file extensions supported by the target. The values specified in this attribute apply only to file:// URIs. When extensions are specified in a target filter, they are generally specified in conjunction with a MIME type of *.

A best practice is to be as specific as possible when specifying the filter criteria, to increase the chances of being selected to handle the invocation request. Wildcard characters (*) are considered a relatively weak match when performing selection, so if your target supports a specific set of types, you must specify each of the types in the filter. In cases where your app supports both specific MIME types and extensions, you should split the registration into two separate filters. One filter registers for the specific types and one filter registers for the extensions against the MIME type of *.

When you declare a target filter, make sure that your filter description follows these rules:

  • The URI value cannot be set as a wildcard character (*). That is, you cannot declare <property var= "uris" value="*"/> in your bar-descriptor.xml file.
  • If the target filter contains actions such as bb.action.VIEW or bb.action.OPEN, has MIME types set as a wildcard character (*), and has the URI attribute set as data:// or file:// or left unstated, then your app cannot be deployed or installed on the device.
  • For a target filter that uses the URI file:// and a MIME type wildcard character (*), to successfully register with the invocation framework, you must also specify a file extension value that is not a wildcard character (*).
  • If you declare a file extension value in the target filter, the file extension value is considered during the brokering and selection process if it is used with a file:// URI.

If your app uses a target filter declaration that is invalid, then when your app is deployed, you will receive the result::failure 884 Restricted Invoke Filter detected error.

Here are some examples of target filters that register successfully with the invocation framework:

  • actions=bb.action.OPEN;types=*;uris=http://;
  • actions=bb.action.OPEN,bb.action.VIEW;types=*;uris=file://;exts=jpg,gif,tif;
  • actions=bb.action.VIEW;types=*;uris=data://;exts=jpg,gif,tif;

The following target filters do not follow the rules specified above and will not allow the app to be deployed or installed on the device:

  • actions=bb.action.OPEN,bb.action.VIEW,bb.action.SET;types=*;uris=file://;
  • actions=bb.action.OPEN;types=*;uris=data://;
  • actions=bb.action.VIEW;types=*;uris=*;
  • actions=bb.action.VIEW;types=*;
  • actions=bb.action.OPEN,bb.action.VIEW;types=*;uris=file://;exts=*;

The following example describes an invoke target that has two filters. The first filter describes the support for bb.action.OPEN and bb.action.VIEW actions on .png and .jpeg image files that are delivered in a file or in the message body. The second filter describes the support for bb.action.OPEN and bb.action.VIEW actions on any URI file with .jpg or .png extensions.

<invoke-target id="com.example.image.view">
  <entry-point-id></entry-point-id>
  <invoke-target-type>application</invoke-target-type>
  <filter>
    <action>bb.action.VIEW</action>
    <action>bb.action.OPEN</action>
    <mime-type>image/png</mime-type>
    <mime-type>image/jpeg</mime-type>
    <property var="uris" value="file://,data://local"/>
  </filter>
  <filter>
    <action>bb.action.VIEW</action>
    <action>bb.action.OPEN</action>
    <mime-type>*</mime-type>
    <property var="uris" value="file://"/>
    <property var="exts" value="jpg,png"/>
  </filter>
</invoke-target>

Last modified: 2014-11-17



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus