Application Integration
Overview
This category contains the packages that enable you to integrate your applications with BlackBerry Device Software applications in a variety of ways that benefit users. This category discusses how to do the following:
- efficiently invoke BlackBerry Device Software applications from third-party applications
- integrate context-sensitive menu options that link to core BlackBerry functionality
- embed BlackBerry multimedia fields directly into your application
- configure you applications to use the BlackBerry phone and messaging capabilities
Invoking Applications
The BlackBerry JDE provides several ways to invoke applications. Follow these guidelines when invoking applications on the BlackBerry device.
Invoking BlackBerry Device Software applications
Use the BlackBerry Invoke API to configure your application to handle specific data in one of the BlackBerry Device Software applications, such as Phone, Tasks, Camera, and BlackBerry Maps.
Packages:
To use this API, invoke invokeApplication(int appType, ApplicationArguments args), passing in application type and any relevant arguments. Optionally, you can pass in null instead of Application arguments. However, if you pass in null, it has the same effect as passing in an ApplicationArguments object create with the default constructor.
Click here to view a BlackBerry Invoke API code sample.
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.blackberry.api.invoke.*;
class appinvo extends UiApplication {
public static void main(String arg[]){
//create a new instance of the application
//and start the application on the event thread
appinvo application = new appinvo();
application.enterEventDispatcher();
}
public appinvo () {
pushScreen(new InnovactionScreen());//creating a screen
}
}
class InnovactionScreen extends MainScreen {
//variables for the user interface
LabelField _title;
EditField _phonefield;
String _value;
public InnovactionScreen() {
super();//invoke MainScreen constructor
//define title of the app
_title = new LabelField("Sample App", LabelField.ELLIPSIS
| LabelField.USE_ALL_WIDTH);
setTitle(_title);
//add user interface field
_phonefield = new EditField("Please Enter a #","");
this.add(_phonefield);//add the field to the MainScreen
//create e-mail menuItem
MenuItem menu1 = new MenuItem("e-mail",1,1) {
public void run () {
//using invoke api to "jump" from this app
//to email app
Invoke.invokeApplication ( Invoke.APP_TYPE_ADDRESSBOOK,
new AddressBookArguments (AddressBookArguments.ARG_COMPOSE));
}
};
//add email menu to the MainScreen
this.addMenuItem(menu1);
//create phone menuItem
MenuItem menu2 = new MenuItem("Phone Them",2,2) {
public void run () {
//getting the value user input in the
//phonefield defined above
_value = _phonefield.getText();
//using invoke api to "jump" from this app
//to phone app
//it calls the number the user types
//in the phonefield
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE,
new PhoneArguments
(PhoneArguments.ARG_CALL, _value));
}
};
this.addMenuItem(menu2);//add phone menu to menuItem
}
} //close InvocationScreen |
Invoking other (non-core) applications
Packages:
The Content Handler API, or CHAPI, defines an optional package of APIs and an execution model for remotely invoking non-core BlackBerry applications. Used together with the Blackberry content handler API, CHAPI is the ideal mechanism for setting invocation parameters for non-core BlackBerry applications. For general information on the CHAPI framework, refer to the javax.microedition.content package overview.
Using CHAPI, you can invoke applications by providing either a URL, content type, or content ID when using one of the constructors available in javax.microedition.content.Invocation class.
Click here to view a CHAPI code sample.
public class ChapiDemo extends UiApplication implements RequestListener
{
//The Content Handler ID.
static final String ID = "com.rim.samples.device.chapidemo";
//The content handler class name.
static final String CLASSNAME = ID + ".ChapiDemo";
// The URL pointing to the location of the file we want to open.
static final String URL = "file:///SDCard/rim.csv";
// Entry point for application
public static void main(String[] args)
{
if( args != null && args.length > 0 && args[0].equals("startup"))
{
registerApp(); // Register this app as a content handler on startup.
}
else
{
new ChapiDemo().enterEventDispatcher(); // GUI
}
}
/**
* Registers this application with specified types, suffixes, actions
* and classname. This method will run on startup.
*/
static void registerApp()
{
try
{
// This app will be a handler for csv files and will be invoked
// with ACTION_OPEN.
String[] types = {"text/csv"};
String[] suffixes = {".csv"};
String[] actions = {ContentHandler.ACTION_OPEN};
// Get access to the registry and register as a content handler.
Registry registry = Registry.getRegistry(CLASSNAME);
registry.register(CLASSNAME,types,suffixes,actions,null,ID,null);
}
catch (ContentHandlerException che)
{
System.out.print(che.toString());
}
catch (ClassNotFoundException cnfe)
{
System.out.print(cnfe.toString());
}
}
// Constructor for GUI app.
ChapiDemo()
{
try
{
// Get access to the ContentHandlerServer for this application and
// register as a listener.
ContentHandlerServer contentHandlerServer = Registry.getServer(CLASSNAME);
// Register as a RequestListener.
contentHandlerServer.setListener(this);
// Push a new GUI screen.
ChapiDemoScreen chapiDemoScreen = new ChapiDemoScreen();
pushScreen(chapiDemoScreen);
}
catch(ContentHandlerException che)
{
System.out.print(che.toString());
}
}
/**
* Creates an Invocation object and passes it to the Registry.
* Called by 'Invoke' menu item.
*/
void doInvoke()
{
try
{
// Create the Invocation with our hard-coded URL.
Invocation invoc = new Invocation(URL);
invoc.setResponseRequired(false); // We don't require a response.
// We want to invoke a handler that has registered with ACTION_OPEN.
invoc.setAction(ContentHandler.ACTION_OPEN);
// Get access to the Registry and pass it the Invocation.
Registry registry = Registry.getRegistry(CLASSNAME);
registry.invoke(invoc);
}
catch (IOException ioe)
{
System.out.print(ioe.toString());
}
}
// Reads text from the file pointed to by the URL contained
// in the Invocation.
static String getViaStreamConnection(Invocation invoc)
{
// Create a StreamConnection and use it to open an
// InputStream for reading.
StreamConnection streamConnection = null;
InputStream inputStream = null;
String text = "";
try
{
streamConnection = (StreamConnection)invoc.open(false);
inputStream = streamConnection.openInputStream();
int ch;
// Read from the InputStream and build text string.
while ((ch = inputStream.read()) != -1)
{
text = text.concat(String.valueOf((char)ch));
}
}
catch(IOException ioe)
{
System.out.print(ioe.toString());
}
finally
{
if (inputStream != null)
{
try
{
inputStream.close();
}
catch(IOException ioe)
{
System.out.print(ioe.toString());
}
}
if (streamConnection != null)
{
try
{
streamConnection.close();
}
catch(IOException ioe)
{
System.out.print(ioe.toString());
}
}
}
return text; // Return the text string.
}
/**
* Implementation of RequestListener
* @param handler <description>
*/
public void invocationRequestNotify(ContentHandlerServer handler)
{
Invocation invoc = handler.getRequest(false);
if(invoc != null)
{
Dialog.alert("Handler has been invoked for: " + invoc.getURL());
String content = getViaStreamConnection(invoc);
if(!"".equals(content))
{
DisplayContentScreen displayContentScreen = new DisplayContentScreen();
displayContentScreen.displayContent(content);
pushScreen(displayContentScreen);
}
}
}
// Simple GUI screen from which to create an Invocation.
final class ChapiDemoScreen extends MainScreen
{
ChapiDemoScreen()
{
// Initialize UI components.
setTitle(new LabelField("Chapi Demo Screen",Field.FIELD_HCENTER));
add(new LabelField("Select Invoke from the menu"));
addMenuItem(new MenuItem("Invoke" , 5, 5)
{
public void run()
{
doInvoke();
}
});
}
}
/**
* This screen will be used to display the content we are handling.
*/
static class DisplayContentScreen extends MainScreen
{
// A field to display content.
TextField _contentField = new TextField(Field.NON_FOCUSABLE);
// Constructor
DisplayContentScreen()
{
setTitle(new LabelField("Display Content Screen",Field.FIELD_HCENTER));
add(_contentField);
}
// Parses the comma separated values in the content string
// and displays the text.
void displayContent(String content)
{
// Let's count the number of commas in the content string.
int commaCount = 0;
for(int i = 0;i < content.length(); i++)
{
if(content.charAt(i) == ',')
commaCount++;
}
// Now we extract the text values from the string and build a new
// string to display in our text field.
int begin = 0;
int end = (content.indexOf(','));
String text = content.substring(begin,end);
for(int i = 0;i < commaCount - 1 ;i++)
{
begin = end + 1;
end = content.indexOf(',',begin);
text = text + "\n" + content.substring(begin,end);
}
begin = end + 1;
text = text + "\n" + content.substring(begin,content.length());
// Display the content.
_contentField.setText(text);
}
}
} |
Invoking the BlackBerry Browser
Packages:
When handling specific MIME-encoded types of data, you may want to render the information directly in the BlackBerry Browser. To do so, use the methods available in the BrowserSession class. For example:
browserSession.displayPage("http://www.BlackBerry.com"); |
To ensure that the BlackBerry Browser can correctly render the data, use the net.rim.blackberry.api.browser BrowserContentProviderRegistry class to add the MIME type to the Browser registry.
Click here for a code sample that illustrates how to launch a BlackBerry Browser session from within a BlackBerry application.
boolean retval = true;
int handle = CodeModuleManager.getModuleHandle("net_rim_bb_browser_daemon");
if (handle <=0 ) {
retval = false;
}
else {
ApplicationDescriptor[] browserDescriptors = CodeModuleManager.getApplicationDescriptors(handle);
if (browserDescriptors == null ) {
retval = false;
}
else
{
if ( browserDescriptors.length <=0 ) {
retval = false;
} else {
String[] args = {"url", "http://URL2LAUNCH.COM"};
ApplicationDescriptor descriptor = new ApplicationDescriptor
(
browserDescriptors[0],
"url invocation", args,
null, -1, null, -1,
ApplicationDescriptor.FLAG_SYSTEM
);
try
{
ApplicationManager.
getApplicationManager().
runApplication(descriptor);
}
catch(ApplicationManagerException e)
{
retval = false;
}
}
}
} |
Integrating Context Menus
Packages:
You can use these packages to integrate BlackBerry context-sensitive menus into your application. For example, you can configure your application to recognize a specific string of numbers as a phone number, and provide a list of menu options when the user clicks on the number.
The net.rim.blackberry.api.menuitem.ApplicationMenuItem class includes the action that will occur once a match is found and is invoked by the BlackBerry smartphone user.
Click here for a code sample on how to configure a zip code lookup in the BlackBerry browser based on a 5 digit string.
public class ZipCodeLookupAppMenuItem extends ApplicationMenuItem
{
private static final long GUID = 0xafcf98f6728f1393L;
private String URL = "http://www.getzips.com/CGI-BIN/ziplook.exe?What=1&Zip=";
private String DEVICE_SIDE = ";deviceside=true";
private String _zipCode;
//using the default constructors here.
ZipCodeLookupAppMenuItem(int order) {
super(order);
}
//methods we must implement
//Run is called when the menuItem is invoked
public Object run(Object context) {
// Context object should be a string contained a zipcode
if(context instanceof String) {
_zipCode = (String)context;
// Create and start the zipcode lookup thread
ZipCodeLookupThread thread = new ZipCodeLookupThread();
thread.start();
}
return context;
}
//toString should return the string we want to
//use as the lable of the menuItem
public String toString() {
return "Lookup ZipCode";
}
private class ZipCodeLookupThread extends Thread {
public void run() {
DataBuffer dbuffer = new DataBuffer();
try {
// Use a StringBuffer to piece together the URL.
StringBuffer sbuffer = new StringBuffer();
sbuffer.append( URL ).append( _zipCode ).append( DEVICE_SIDE );
HttpConnection connection = (HttpConnection)Connector.open( sbuffer.toString() );
InputStream input = connection.openInputStream();
// Read in the data from the InputStream
byte[] temp = new byte[ 1024 ];
for( ;; ) {
int bytesRead = input.read( temp );
if( bytesRead == -1 ) {
break;
}
dbuffer.write( temp, 0, bytesRead );
}
input.close();
connection.close();
} catch( IOException e ) {
EventLogger.logEvent( GUID, e.toString().getBytes() );
}
try {
// Create the ByteArrayOutputStream that will be used to capture
// the Base64 encoded data.
ByteArrayOutputStream output = new ByteArrayOutputStream();
Base64OutputStream boutput = new Base64OutputStream( output );
output.write( "data:text/html;base64,".getBytes() );
boutput.write( dbuffer.getArray() );
boutput.flush();
boutput.close();
output.flush();
output.close();
// Launch the browser using the base64 encoded data above.
BrowserSession bSession = Browser.getDefaultSession();
String data = output.toString();
bSession.displayPage( data );
} catch( IOException e ) {
EventLogger.logEvent( GUID, e.toString().getBytes() );
}
}
}
} |
The net.rim.blackberry.api.stringpattern.PatternRepository class registers a Perl-style regular expression or a specific string with the systems pattern repository. When a match is found, the ApplicationMenuItem(s) associated with the patterns appear in the current application's menu.
Click here for a code sample on registering the ApplicationMenuItem configured in the previous code sample.
public class ZipCodeLookupMain extends Application
{
public static void main( String[] args )
{
// Start a new app instance for Zipcode lookup operations
ZipCodeLookupMain instance = new ZipCodeLookupMain();
instance.enterEventDispatcher();
}
// using the default constructors here.
public ZipCodeLookupMain()
{
// Create an array of menu items to be associated with pattern
ZipCodeLookupAppMenuItem zipCodeAppMenuItem = new ZipCodeLookupAppMenuItem(0);
ApplicationMenuItem[] zipCodeMenuArray = new ApplicationMenuItem[1];
zipCodeMenuArray[0] = zipCodeAppMenuItem;
// Add a pattern to the Pattern Repository.
PatternRepository.addPattern( ApplicationDescriptor.currentApplicationDescriptor(),
"\\d{5}", PatternRepository.PATTERN_TYPE_REGULAR_EXPRESSION, zipCodeMenuArray );
}
} |
Embedding BlackBerry Multimedia Fields
You can view a variety of multimedia content in your application, such as BlackBerry camera pictures, or web/MMAPI images or video. For more information on embedding BlackBerry multimedia in your application, refer to (MM Category link).
Using BlackBerry Phone and Messaging APIs in your application
Packages:
You can use specific BlackBerry packages to extend your applications so users can send and receive phone calls and messages. To invoke the Phone API from your application, use one of the following methods: invoke.InvokeApplication, which is shown in the above sample code for "Invoking BlackBerry Device Software applications"; and initiateCall(int lineId, String dest), where lineId is the source line ID, and dest is the phone number you want to call.
Alternatively, you can implement PhoneListener to set your application to automatically trigger Phone API features based on events.
Click here for a code sample that implements the PhoneListener interface.
Click here for a code sample that implements the PhoneListener interface.
package com.samples.phoneCallListenerSample; import net.rim.blackberry.api.phone.*; import net.rim.device.api.ui.container.FlowFieldManager; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.component.Status; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.system.*; public final class PhoneCallListenerSample extends Application implements PhoneListener { static public void main(String[] args) { PhoneCallListenerSample plSample = new PhoneCallListenerSample(); plSample.enterEventDispatcher(); } private PhoneCallListenerSample() { System.out.println("###PhoneCallListenerSample: Registering listener..."); Phone.addPhoneListener(this); System.out.println("###PhoneCallListenerSample: Listener registered."); } private void showPhoneEvent(String reason, int callId) { Status.show("Phone event: " + reason + "\n" + "CallID: " + callId, Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION), 4000, Status.GLOBAL_STATUS, true, false, 2); System.out.println("###PhoneCallListenerSample: Phone event: " + reason + " for callID: " + callId); } // A call has been added to a conference call public void callAdded(int callId) { showPhoneEvent("Call Added", callId); } // User answered a call public void callAnswered(int callId) { showPhoneEvent("Call Answered", callId); } // Conference call established public void callConferenceCallEstablished(int callId) { showPhoneEvent("Conference Call Established", callId); } // Network indicates a connected event public void callConnected(int callId) { showPhoneEvent("Call Connected", callId); } // Direct-connect call connected public void callDirectConnectConnected(int callId) { showPhoneEvent("DirectConnect Connected", callId); } // Direct-connect call disconnected public void callDirectConnectDisconnected(int callId) { showPhoneEvent("DirectConnect Disconnected", callId); } // Call disconnected public void callDisconnected(int callId) { showPhoneEvent("Call Disconnected", callId); } // User ended call public void callEndedByUser(int callId) { showPhoneEvent("Call Ended By User", callId); } // Call has been placed on "hold" public void callHeld(int callId) { showPhoneEvent("Call Held", callId); } // New call has arrived public void callIncoming(int callId) { showPhoneEvent("Call Incoming", callId); } // Outbound call initiated by the handheld public void callInitiated(int callid) { showPhoneEvent("Call Initiated", callid); } // Call removed from a conference call public void callRemoved(int callId) { showPhoneEvent("Call Removed", callId); } // Call taken off of "hold" public void callResumed(int callId) { showPhoneEvent("Call Resumed", callId); } // Call is waiting public void callWaiting(int callid) { showPhoneEvent("Call Waiting", callid); } // Conference call has been terminated // (all members disconnected) public void conferenceCallDisconnected(int callId) { showPhoneEvent("Conference Call Disconnected", callId); } // Call failed public void callFailed(int callId, int reason) { String errMsg = "Call Failed due to "; // determine reason switch( reason ) { case PhoneListener.CALL_ERROR_AUTHORIZATION_FAILURE: showPhoneEvent(errMsg + "Authorization Error", callId); break; case PhoneListener.CALL_ERROR_CALL_REPLACED_BY_STK: showPhoneEvent(errMsg + "Call Replaced By Stack", callId); break; case PhoneListener.CALL_ERROR_CONGESTION: showPhoneEvent(errMsg + "Congestion", callId); break; case PhoneListener.CALL_ERROR_CONNECTION_DENIED_BY_NETWORK: showPhoneEvent(errMsg + "Connection Denied", callId); break; case PhoneListener.CALL_ERROR_DUE_TO_FADING: showPhoneEvent(errMsg + "Fading", callId); break; case PhoneListener.CALL_ERROR_EMERGENCY_CALLS_ONLY: showPhoneEvent(errMsg + "Emergency Calls Only", callId); break; case PhoneListener.CALL_ERROR_FDN_MISMATCH: showPhoneEvent(errMsg + "FDN Mismatch", callId); break; case PhoneListener.CALL_ERROR_GENERAL: showPhoneEvent(errMsg + "General Error", callId); break; case PhoneListener.CALL_ERROR_HOLD_ERROR: showPhoneEvent(errMsg + "Hold Error", callId); break; case PhoneListener.CALL_ERROR_INCOMING_CALL_BARRED: showPhoneEvent(errMsg + "Incoming Call Barred", callId); break; case PhoneListener.CALL_ERROR_LOST_DUE_TO_FADING: showPhoneEvent(errMsg + "Lost Due To Fading", callId); break; case PhoneListener.CALL_ERROR_MAINTENANCE_REQUIRED: showPhoneEvent(errMsg + "Maintenance", callId); break; case PhoneListener.CALL_ERROR_NUMBER_NOT_IN_SERVICE: showPhoneEvent(errMsg + "Number Not In Service", callId); break; case PhoneListener.CALL_ERROR_NUMBER_UNOBTAINABLE: showPhoneEvent(errMsg + "Number Unobtainable", callId); break; case PhoneListener.CALL_ERROR_OUTGOING_CALLS_BARRED: showPhoneEvent(errMsg + "Outgoing Calls Barred", callId); break; case PhoneListener.CALL_ERROR_PLEASE_TRY_LATER: showPhoneEvent(errMsg + "Try Later", callId); break; case PhoneListener.CALL_ERROR_RADIO_PATH_UNAVAILABLE: showPhoneEvent(errMsg + "Radio Path Unavailable", callId); break; case PhoneListener.CALL_ERROR_SERVICE_CONFLICT: showPhoneEvent(errMsg + "Service Conflict", callId); break; case PhoneListener.CALL_ERROR_SERVICE_NOT_AVAILABLE: showPhoneEvent(errMsg + "Service Not Available", callId); break; case PhoneListener.CALL_ERROR_SUBSCRIBER_BUSY: showPhoneEvent(errMsg + "Subscriber Busy", callId); break; case PhoneListener.CALL_ERROR_SYSTEM_BUSY_TRY_LATER: showPhoneEvent(errMsg + "System Busy", callId); break; case PhoneListener.CALL_ERROR_TRY_AGAIN: showPhoneEvent(errMsg + "Try Again", callId); break; case PhoneListener.CALL_ERROR_USER_BUSY_IN_DATA: showPhoneEvent(errMsg + "User Busy In Data", callId); break; case PhoneListener.CALL_ERROR_USER_BUSY_IN_PRIVATE: showPhoneEvent(errMsg + "User Busy In Private", callId); break; case PhoneListener.CALL_ERROR_USER_NOT_AUTHORIZED: showPhoneEvent(errMsg + "Not Authorized", callId); break; case PhoneListener.CALL_ERROR_USER_NOT_AVAILABLE: showPhoneEvent(errMsg + "User Not Available", callId); break; case PhoneListener.CALL_ERROR_USER_NOT_REACHABLE: showPhoneEvent(errMsg + "User Not Reachable", callId); break; } } |
Copyright 1999-2008 Research In Motion Limited. 295 Phillip Street, Waterloo, Ontario, Canada, N2L 3W8. All Rights Reserved.
Copyright 1993-2003 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
Copyright 2002-2003 Nokia Corporation All Rights Reserved.
Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.