Using the Invocation Framework from ActionScript

Adobe AIR Development

TITLE_IMAGE

Beta 2 of the BlackBerry® 10 SDK for Adobe® AIR® now has support for participating in the BlackBerry 10 Invoke Framework. You can find all of the APIs in the QNXDevice.ane and they are all documented.

Invoking a Application

By leveraging the Invoke API, you can invoke virtually any other application on the BlackBerry® smartphone through some simple API call, where you’ll set a parameter for the app you want to invoke and then pass in any parameters that application is expecting. A typical example would be that your application can invoke the BlackBerry® Maps application when it comes across an address. InvokeManager.invoke() will invoke an application.

When the application has been successfully invoked, an InvokeEvent.INVOKE_TARGET event will be dispatched. If there was an error invoking the target, an ErrorEvent.ERROR event will be dispatched. Please refer to the following Knowledge Base article for details on some known issues which will be addressed in an upcoming patch.

Invoking a Viewer

InvokeManager.invokeViewer() will invoke a viewer. A Viewer class is returned and is used to communicate with the viewer.

Let’s say you have an image viewer application and you want to invoke it from the main application you’re working on. In the main application, you want to pass the image file that the imager viewer app will open when invoked.

Below is a sample of how you can invoke a viewer and wait for it to be created. This example assumes that you have created the viewerRequest object with the correct data for your viewer.

var viewer:Viewer = InvokeManager.invokeManager.invokeViewer( viewerRequest );
viewer.addEventListener( ViewerEvent.VIEWER_CREATED, viewerCreated );

private function viewerCreated( event:ViewerEvent ):void
{
   //viewer is created and ready to communicate with.
}

Making your Application an Invoke Handler

If you are developing an application that can be invoked by another application, you will want to add a listener for the invoke event at the very start of your application. These should be the first lines of your application.
Once you have received the invoke event, you can check the startup mode and get the data that you were invoked with.
Below is a sample of how you would accomplish this:

InvokeManager.invokeManager.addEventListener(InvokeEvent.INVOKE, onInvoked );
private function onInvoked( event:InvokeEvent ):void
{
    if( InvokeManager.invokeManager.startupMode == InvokeStartupMode.INVOKE )
    {
        var invokeRequest:InvokeRequest = InvokeManager.invokeManager.startupRequest;
    }
    else if( InvokeManager.invokeManager.startupMode == InvokeStartupMode.VIEWER )
    {
        var viewerRequest:InvokeViewerRequest = InvokeManager.invokeManager.startupViewerRequest;
    }
}

Query a list of targets

You can also query a list of targets or viewers on the device by calling the InvokeManager.queryTargets() method. At some point in the future, this will make a pop-up list in your application that will allow users to select items from the list. For now, it returns the results and it is up to you to use those values in your invoke() and invokeViewer() calls.

InvokeEvent

No matter how your application is started, you will receive an InvokeEvent dispatched by the InvokeManager. In order to determine how your app was started, you can check the InvokeManager.startupMode in your InvokeEvent handler. So, your application would look something like the following, assuming that your application can be launched as a target and a viewer:

package
{
    import qnx.events.InvokeEvent;
    import qnx.invoke.*;

    public class Main extends Sprite
    {

        public function Main()
        {
            //NOTE: THIS MUST BE THE FIRST THING SET IN YOUR APPLICATION CONSTRUCTOR
            InvokeManager.invokeManager.addEventListener(InvokeEvent.INVOKE, onInvoke );
        }

        private function onInvoke( event:InvokeEvent ):void
        {
            if( InvokeManager.invokeManager.startupMode == InvokeStartupMode.INVOKE )
            {
                //invoked as an application/target.
                var data:InvokeRequest = InvokeManager.invokeManager.startupRequest;
            }
            else if( InvokeManager.invokeManager.startupMode == InvokeStartupMode.VIEWER )
            {
                //invoked as a viewer
                var data:InvokeViewerRequest = InvokeManager.invokeManager.startupViewerRequest;
            }
            else
            {
                //launched by the pressing on the icon on the home screen.
            }
        }
    }
}

Closing a Viewer

There are two different ways a viewer can be closed:

  1. From the application
  2. From the viewer

When an application wishes to close a viewer that it has created, it can simply call the Viewer.dispose() method. This will cause the viewer to be removed immediately.

A viewer can request to be closed by the application and should never actually attempt to close itself directly. Viewers can call the InvokeManager.requestViewerClose() method. This will send a message to the application requesting that it be closed. The Viewer instance in the application will dispatch a ViewerEvent.VIEWER_CLOSE_REQUEST event. When application receives this event, it should call the dispose() method on the viewer to close it. The reason this doesn’t happen automatically is so that applications can transition viewers out before removing them. We may make this a bit more automated in the future, and we’ll let you know when this happens.

Viewer message relay

Viewers can send data to applications using the InvokeManager.viewerSendMessage() method. The Viewer instance will then dispatch ViewerEvent.VIEWER_MESSAGE events with the message and data properties set to what was passed into the viewerSendMessage(). Here is an example of how you would use this:

Viewer code

InvokeManager.invokeManager.viewerSendMessage( "select", {name:"Fred"});

App Code

__currentViewer = InvokeManager.invokeManager.invokeViewer(viewerRequest);
__currentViewer.addEventListener( ViewerEvent.VIEWER_MESSAGE, onMessage );

private function onMessage( e:ViewerEvent ):void
{
    trace( e.message, e.data ); //outputs "select Fred";
}

About Tim N.

Tim leads Application Platform & Tools Product Management at Research In Motion. This includes APIs, Frameworks and Tools for the BlackBerry Platform. He can be found hanging out in the development forums or Twitter (@brcewane) trying to help out where he can and to bring your feedback into the next releases of BlackBerry tooling. You’ll also see Tim presenting various topics at the BlackBerry Developer Conferences and BlackBerry World so be sure to stop by and say hi. Just don’t start talking about cars or Batman or you won’t be able to get rid of him.

Join the conversation

Show comments Hide comments
+ -
blog comments powered by Disqus