Invoking cards

Cards enhance the invocation framework's capabilities by allowing apps to share the UI and the app logic with other apps. You send a request to invoke a card in the same way as an invocation request for an app, which means that everything that applies to sending an invocation request applies to cards as well.

Here's how you can use the invocation framework to import a card from another app:

Not applicable

// Create and send an invocation for the card target
InvokeManager* invokeManager = new InvokeManager();
InvokeRequest cardRequest;

// Set the target card
cardRequest.setTarget("com.example.myapp");

// Set the action that the target card should execute
cardRequest.setAction("bb.action.VIEW");

// Set the MIME type
cardRequest.setMimeType("image/png");

// Set the URI of the content
cardRequest.setUri("file://path/to/document.pdf");

// Invoke the target card
InvokeTargetReply* reply = invokeManager->invoke(cardRequest);

// Take ownership of the reply
reply->setParent(this);

Before a new card is invoked and allowed to be stacked, the BlackBerry 10 OS verifies that the client app is not already parenting a card. Unlike an app, a card may continue to exist in multiple instances, but a parent app (or card) can parent only one card at a time. This is important because multiple instances of a card may be running at the same time.

Cards support a "fire and forget" import model. However, for apps that require notifications and additional feedback, cards also provide peek notifications and response data.

Listen for peek events

Cards offer a parent card or an app the ability to receive notifications when a user peeks at another card. This is important if you want your app to display content differently during a peek event.

Here's how you can enable your app to listen for peek events:

Not applicable

// Connect the peekStarted() and peekEnded() signals
                   
// 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(peekStarted(bb::system::CardPeek::Type)), 
                                 parent, SLOT(peekStarted(bb::system::CardPeek::Type)));
// This is only available in Debug builds
Q_ASSERT(connectResult);
 
connectResult = QObject::connect(invokeManager, SIGNAL(peekEnded()),
                                 parent, SLOT(peekEnded()));
// This is only available in Debug builds
Q_ASSERT(connectResult);

// ...
  
void peekStarted(bb::system::CardPeek::Type peekType)
{
    // If needed, adjust the content based on peek type (parent peek/root peek)
}
  
void peekEnded()
{
    // Revert to non-peek state
}

Listen for a card response message

A card can send a response message to the parent app when a card completes its task. For example, a picker card can return the data that a user selects to the client app.

Here's how you can listen for card response messages:

Not applicable

// 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 = connect(invokeManager, SIGNAL(childCardDone(const bb::system::CardDoneMessage&)), 
                        this, SLOT(childCardDone(const bb::system::CardDoneMessage&)));
                        
// This is only available in Debug builds
Q_ASSERT(connectResult);

void App::childCardDone(const bb::system::CardDoneMessage &message)
{
    // Read message here
}

If you're using previewer or composer cards, you don't usually need to handle a response. You should design your previewer and composer cards so that any response is optional.

Close a card

An app can request to close a card that it imported. As a result, the card is transitioned off of the screen. When a user closes the card, both the app and the card are notified. However, if the card is closed by the app itself, the card cannot provide a response. Also, when an app closes a card, it closes the entire stack of cards (including children of the card) above it.

Here's how your app can request to close a child card:

Not applicable

invokeManager->closeChildCard();

Last modified: 2014-11-17



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

comments powered by Disqus