Would you like to tell us how we are doing?

You bet No thanks

Sorry about the red box, but we really need you to update your browser. Read this excellent article if you're wondering why we are no longer supporting this browser version. Go to Browse Happy for browser suggestions and how to update.

Highly contextualized

A highly contextualized app is one that can gather information about a BlackBerry device's context without having to ask the user. It can use this information to enhance the experience of its users. All apps can access the GPS radio, an accelerometer, a magnetometer, comprehensive APIs for gathering BlackBerry device information, and reliable connectivity to a wide variety of web services.

What makes an app highly contextualized? Let's look at the Clock application on a BlackBerry device for an example. When you travel between time zones, the Clock application offers to reset your home time zone to the time zone that you have traveled to. This feature improves the application in two ways. First, the user is reminded to update their time zone. And second, the user is presented with the correct time for the zone they're in. They only have to press a button to confirm that they want the Clock application to make the change. In comparison, a typical BlackBerry app will only perform a task in response to user input: it doesn't take actions without prompt, and it doesn't prompt for actions based on the situation. What differentiates a highly contextualized app from a regular app is initiative.

What are the benefits of a highly contextualized app?

  • Improve the user experience. Apps that anticipate user needs and prompt users to verify input are frequently easier to use.
  • Reduce input errors. Getting geographical coordinates of a device's current location by using the GPS radio is much less error prone than asking a user to enter the name of the city they are currently in.
  • Lower support costs. Less user input and more contextually intelligent presentation of features can result in fewer support calls about how to invoke a feature or how to enter information in the correct format.

Approaches to adding context

You can make your app highly contextualized by using any of the following approaches.

Approach

Examples

Add connectivity context

You can check the type of network connections that are available. For example, if the user requests that the app download and play a large video file when the device is roaming on a wireless network, the app should warn the user that the download might be expensive. Your app might also leverage a web service to determine roaming rates and calculate the approximate cost.

If the device is connected to a low-cost but very low-bandwidth Wi-Fi connection, the app should warn the user that the download might take a very long time. The app might provide an approximate download time, and let the user decide whether to proceed.

Add battery level context

Your can check the power level of the battery before performing tasks that consume a lot of power. Your app can let the user know that they are about to perform a task that consumes a lot of power and that their battery is low. It could also stop doing any unnecessary background processing or prefetching.

Add device characteristics context

Your app should adapt to the device model it is running on. Battery life and connectivity are universal contexts for BlackBerry apps. But device characteristics such as the available keyboard types, screen type and dimensions, audio capabilities, inserted memory cards, and the presence of an accelerometer are specific to the particular BlackBerry device.

Your app should provide good default choices for users. For example, on a device with a touch screen that supports gestures, your app could display hints about how to zoom in and out using pinch gestures.

Use contextual menus

Your app should provide users with options that make sense based on what the users are currently doing within the app. Use pop-up menus to provide users with a quick way to access the most common actions for a highlighted item.

Add location context

You can automatically incorporate the current location of a user's BlackBerry device into search criteria. For example, users searching for gas stations are likely most interested in ones near their current location. Many web services provide location-specific services. Your app can use those services.

Add time context

You can add time context to your apps to increase the relevance of search results. For example, if a user searches for restaurants near them, you could arrange the results by distance from their location, and use the restaurant's hours of operation to only return restaurants that are currently open.

Add date context

You can customize the actions of your app based on the current date. For example, your app could display a custom theme for a user's birthday, or for holidays. Your app should customize its actions according to the current date when possible. Doing so could improve the user experience.

Adding connectivity context

Roaming cellular connections are widely available, but if your app transfers large amounts of data over them, you can inadvertently end up costing your users large sums of money. You can add connectivity context by checking if a Wi-Fi connection is available.

Your app can determine the type of network the device is connected to, discover and interpret signal levels, and check if a device is using a roaming cellular connection. You can then program your app to react accordingly.

You can use RadioInfo.getSignalLevel() to get the signal level of the current connection. The following table can help you interpret the results.

Network type Strong signal Medium signal Weak signal
GSM > -76 dBm -86 dBm to -92 dBm < -101 dBm
CDMA > -83 dBm -92 dBm to -105 dBm < -109 dBm
Wi-Fi > -50 dBm -70 dBm to -60 dBm < -80 dBm

Use the NETWORK_SERVICE_ROAMING constant to determine if a device is currently using a roaming cellular connection, as demonstrated in the following code sample.

Code Sample: Checking radio signal level

int networkService = RadioInfo.getNetworkService();
if ( (networkService & RadioInfo.NETWORK_SERVICE_ROAMING) != 0)
{
   //BlackBerry device is using a roaming connection
}

Adding battery level context

Power level change events

Your can register your app so it is notified when power level change events take place on the device it is running on. If the battery power level is low, you can respond by turning off or modifying some features of your app to conserve power. When your app receives notification that the battery power level is good again, you can turn on those features again.

To process power level change events, your app must implement the net.rim.device.api.system.SystemListener interface.

The following code sample demonstrates how to implement the SystemListener interface.

import java.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;

public class PowerChangeEvent
extends Application implements SystemListener
{
   public static PowerChangeEvent theApp;

   public static void main(String args[])
   {
      theApp = new PowerChangeEvent();
      theApp.enterEventDispatcher();
   }

   public PowerChangeEvent()
   {
      Application.getApplication().addSystemListener(this);
      System.out.println("PowerChangeEvent: PowerChangeEvent has started!");
   }

   public void powerOff()
   {
      System.out.println("PowerChangeEvent: The device is powering off.");
   }

   public void powerUp()
   {
      System.out.println("PowerChangeEvent: The device is powering up.");
   }

   //Invoked when the internal battery voltage falls below a critical level.
   public void batteryLow()
   {
      System.out.println("PowerChangeEvent: The battery is getting low!");
   }

   //Invoked when the internal battery voltage has returned to normal.
   public void batteryGood()
   {
      System.out.println("PowerChangeEvent: The battery level is now good!");
   }

   //Invoked when the internal battery state has changed.
   //Not used in this sample.
   public void batteryStatusChange(int status)
   {
   }
}

Adding BlackBerry device characteristics context

There are a number of methods, mostly in classes in the net.rim.device.api.system package, that provide information about a device. The following is a list of some common device information you can get using those methods. Most of the methods are static. Some of the methods return integral types that represent a set of bit flags. When that is the case, the class includes bit masks you can use to extract the information.

Device characteristic

Method

Identity

device is simulator

DeviceInfo.isSimulator()

manufacturer

DeviceInfo.getManufacturerName()

device name

DeviceInfo.getDeviceName()

PIN

DeviceInfo.getDeviceId()

IMSI

SIMCardInfo.getIMSI()

ESN

CDMAInfo.getESN()

MEID

CDMAInfo.getHexMEID()

IMEI

GPRSInfo.getIMEI()

owner information

OwnerInfo.getOwnerInformation()

owner name

OwnerInfo.getOwnerName()

vendor ID

Branding.getVendorId()

branding data version

Branding.getVersion()

branding data is signed

Branding.isDataSigned()

Battery

battery power level (%)

DeviceInfo.getBatteryLevel()

additional battery information

DeviceInfo.getBatteryStatus()

battery temperature (°C)

DeviceInfo.getBatteryTemperature()

battery voltage (mV)

DeviceInfo.getBatteryVoltage()

battery is removable

DeviceInfo.isBatteryRemovable()

Speaker and Headset

audio is supported

Audio.isSupported()

codec is supported

Audio.isCodecSupported()

volume level (%)

Audio.getVolume()

headset is built-in

Audio.hasBuiltInHeadset()

headset is connected

Audio.isHeadsetConnected()

Accelerometer

accelerometer is supported

AccelerometerSensor.isSupported()

Flip Sensor

flip is open or closed

Sensor.getState()

phone is flip

Sensor.isSupported()

Holster Sensor

phone is in holster

Sensor.getState()

holster sensor is supported

Sensor.isSupported()

Slide Sensor

sliding keyboard is supported

Sensor.isSupported()

slide is open

Sensor.isSlideOpened()

slide is closed

Sensor.isSlideClosed()

slide is moving

Sensor.isSlideInTransition()

Display

horizontal resolution (pixels per meter)

Display.getHorizontalResolution()

vertical resolution (pixels per meter)

Display.getVerticalResolution()

drawable area height (pixels)

Display.getHeight()

drawable area width (pixels)

Display.getWidth()

number of display colors

Display.getNumColors()

additional display information

Display.getProperties()

Backlight

backlight is on

Backlight.isEnabled()

backlight brightness (%)

Backlight.getBrightness()

backlight brightness is configurable

Backlight.isBrightnessConfigurable()

backlight brightness default (%)

Backlight.getBrightnessDefault()

default backlight timeouts

Backlight.getTimeoutDefault()

LED Indicator

LED is supported

LED.isSupported()

LED is multi-color

LED.isPolychromatic()

Radios

wireless access family is supported

RadioInfo.getSupportedWAFs()

GPS

GPS mode is available

GPSInfo.isGPSModeAvailable()

default GPS mode

GPSInfo.getDefaultGPSMode()

Bluetooth

Bluetooth radio is supported

BluetoothSerialPort.isSupported()

Bluetooth information

BluetoothSerialPort.getSerialPortInfo()

Phone

phone number

Phone.getDevicePhoneNumber()

voice mail is present

Phone.isVoiceMailIndicatorOn()

Memory

flash memory size (bytes)

DeviceInfo.getTotalFlashSizeEx()

free flash memory (bytes)

Memory.getFlashFree()

RAM statistics

Memory.getRAMStats()

OS and software

platform version

DeviceInfo.getPlatformVersion()

software version

DeviceInfo.getSoftwareVersion()

Camera

camera is supported

DeviceInfo.hasCamera()

USB port

USB port is supported

USBPort.isSupported()

USB connection state

USBPort.getConnectionState()

Adding location context

Accessing and displaying GPS location information

Your app can access GPS data and the location, speed, and direction of the BlackBerry device. Your app can use a source for GPS data that provides data within specific accuracy parameters, at a specific cost, and uses a specific amount of battery power.

A BlackBerry device creates an object of the javax.microedition.location.Criteria class and invokes the methods of the class to specify the source of GPS data. For example, an app can invoke Criteria.setHorizontalAccuracy(2) and Criteria.setVerticallAccuracy(2) to specify that a source of GPS data must provide vertical and horizontal data values that is accurate within 2 meters of the actual values. An app can invoke Criteria.setCostAllowed(true) to use a source of GPS data that costs money to use. The app can invoke Criteria.setPreferredPowerConsumption(POWER_USAGE_LOW) to use a source of GPS data that makes minimal use of the battery power on a BlackBerry device.

An app sets the properties of the Criteria object to specify the mode the app uses to retrieve GPS data. The cell site mode allows an app to retrieve GPS data from a cell site tower. This mode is faster but less accurate than other modes. The assisted mode allows an app to retrieve GPS data from a satellite. This mode is faster than the autonomous mode and more accurate than the cell site mode. The autonomous mode allows an app to retrieve GPS data from the device. This mode is slower but more accurate than other modes.

After creating and setting the properties of the Criteria object, an app invokes javax.microedition.location.LocationProvider.getInstance(Criteria) using the Criteria object as a parameter to retrieve a LocationProvider object. An app can invoke LocationProvider.getLocation() to retrieve an object of the javax.microedition.location.Location class to access data for a location.

Invoking the Location.getSpeed() and Location.getCourse() methods retrieves the speed and the direction of the BlackBerry device. Invoking the Location.getQualifiedCoordinates() method retrieves a javax.microedition.location.QualifiedCoordinates object that can provide the latitudinal and longitudinal coordinates of the device.

An app can listen for updates from a source for GPS data to provide a BlackBerry device user with current GPS information. The app must implement the javax.microedition.location.LocationListener interface and invoke the LocationProvider.setLocationListener(LocationListener int, int, int) method to register the LocationListener with a LocationProvider.You can invoke LocationProvider.setLocationListener(LocationListener int, int, int) and use an integer value as the interval argument to specify how often, in seconds, the app checks for new GPS data.

Here's how to retrieve the location of a BlackBerry device.

Import the required classes.

import javax.microedition.location.*;

Create a class and a constructor.

public class handleGPS
{
   public handleGPS()
   {
   }
}

Declare static fields in the class.

static GPSThread gpsThread;
static double latitude;
static double longitude;

In the constructor, create and start a local thread.

gpsThread = new GPSThread();
gpsThread.start();

In the class, create a private class that extends Thread, and create a run() method.

private class GPSThread extends Thread
{
   public void run()
   {
   }
}

In the run() method, create an instance of the Criteria class. Invoke setCostAllowed(false) to specify the autonomous mode.

Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);

In the run() method, create a try/catch block. In the block create a LocationProvider object by getting an instance of the Criteria object. Create another try/catch block to create a Location object to request the current location of the BlackBerry device and specify the timeout period in seconds. When the getLocation() method returns, request the latitude and longitude coordinates.

try
{
    LocationProvider myLocationProvider =
        LocationProvider.getInstance(myCriteria);

    try
    {
        Location myLocation = myLocationProvider.getLocation(300);
        latitude  = myLocation.getQualifiedCoordinates().getLatitude();
        longitude = myLocation.getQualifiedCoordinates().getLongitude();
    }
    catch ( InterruptedException iex )
    {
        return;
    }
    catch ( LocationException lex )
    {
        return;
    }
}
catch ( LocationException lex )
{
    return;
}
return;

Using contextual menus

Pop-up menus and submenus

You can add a pop-up menu and a submenu to your app by using the classes provided in the net.rim.device.api.ui.menu package. These menus can help you provide context by presenting relevant controls to your users.

Menu

Description

Pop-up menu

A pop-up menu, similar to a context menu, contains a list of the most common actions that BlackBerry device users can perform within the current context. An item in the pop-up menu can include the text, an application icon, and a command.

A pop-up menu replaces a context menu, or a short menu, that was available in previous versions of the BlackBerry Java SDK. The BlackBerry Device Software automatically converts an existing context menu into a pop-up menu.


This screen shows a pop-up menu.

Submenu

A submenu is a group of related menu items. A submenu appears as a subset of a menu item in the full menu. When you include items in a submenu, users can find frequently-used items or important items more easily in the full menu.


This screen shows an example of a full menu item and the submenu associated with it.

Creating a pop-up menu

You can create a pop-up menu by using classes that are available in the net.rim.device.api.ui.menu package, and you can define the functionality of the pop-up menu items by using the Command Framework API.

A pop-up menu consists of a context menu provider, a command item provider, and command items.

Component

Description

Context menu provider

You use the DefaultContextMenuProvider class to create and display a screen's pop-up menu. When a BlackBerry device user opens a pop-up menu, the context menu provider looks for fields on the screen that are command item providers. DefaultContextMenuProvider is the default implementation of ContextMenuProvider. If you do not provide a screen with a context menu provider, the legacy context menu is converted and displayed as a pop-up menu.

Command item provider

You use the CommandItemProvider class to configure a field on your UI screen so that the field can provide context and command items to the pop-up menu based on the current context. For example, you could configure an email address as a command item provider and provide the user with different actions based on whether the email address is in the user's contact list.

Command items

You use the CommandItem class to specify the text, icon, and behavior of a pop-up menu item. You define the behavior of the pop-up menu by using a command. The command acts as a proxy to an instance of a command handler, which defines the functionality of the pop-up menu item. For example, for an email address, you could provide command items to add or view a contact based on whether the selected email address appears in the user's contact list. The command handler would contain the code to add or view the contact.

For more information on commands and command handlers, see Command Framework API. The Command Framework sample app that is provided in the BlackBerry Java SDK demonstrates commands and command handlers.

If you use a legacy context menu, BlackBerry Device Software 6.0 converts the context menu items to command items and provides them to the command item provider. For more information, see Support for legacy context menus.

Here's how to create a pop-up menu.

Import the required classes and interfaces.

import net.rim.device.api.command.*;
import net.rim.device.api.system.*;
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.ui.menu.*;
import net.rim.device.api.ui.image.*;
import net.rim.device.api.util.*;
import java.util.*;

Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the app to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the app. The MyPopUpMenuScreen class represents the custom screen.

public class MyPopUpMenuApp extends UiApplication 
{
    public static void main(String[] args)
    {
        Mypop-upMenuApp theApp = new Mypop-upMenuApp();
        theApp.enterEventDispatcher();
    }
    
    public Mypop-upMenuApp()
    {
       	pushScreen(new Mypop-upMenuScreen());
    } 
}

Create the custom screen for the app by extending the MainScreen class. In the screen constructor, invoke setTitle() to specify the title for the screen.

class MyPopUpMenuScreen extends MainScreen
{
    EmailAddressEditField emailAddress;
    public Mypop-upMenuScreen()
    {       
        setTitle("Pop-Up Menu Demo");
    }
}

In the screen constructor, specify a context menu provider. Pass a DefaultContextMenuProvider object to Screen.setContextMenuProvider() to enable your screen to display a pop-up menu.

setContextMenuProvider(new DefaultContextMenuProvider());

In the screen constructor, create UI components that can invoke the pop-up menu. In the following code sample, the label uses the Field.FOCUSABLE property to allow users to highlight the field.

LabelField labelField = new LabelField("Click to invoke pop-up menu", Field.FOCUSABLE);
emailAddress = new EmailAddressEditField("Email address: ", "name@blackberry.com", 40);

In the screen constructor, configure the UI components as command item providers. The DefaultContextMenuProvider object looks for fields that are configured as command item providers, and uses them to create and display a pop-up menu. For each component, invoke Field.setCommandItemProvider() to configure the field as a command item provider.

ItemProvider itemProvider = new ItemProvider();
                       
labelField.setCommandItemProvider(itemProvider);
emailAddress.setCommandItemProvider(itemProvider);

In the custom screen, implement the CommandItemProvider interface. In getContext(), return the field that is configured as a command item provider. In getItems(), create a Vector object to add the pop-up menu items to.

class ItemProvider implements CommandItemProvider 
{
    public Object getContext(Field field)
    {
        return field;
    }
    public Vector getItems(Field field)
    {
    }
}

In getItems(), provide the pop-up menu items by creating instances of the CommandItem class. For each command item, specify the pop-up menu text, icon, and command. In this example, an if-then-else statement is used to check which component invoked the pop-up menu before creating the CommandItem. The command is a proxy to an instance of a class that extends the abstract CommandHandler class. Invoke Vector.addElement() to add the pop-up menu items to the Vector. Return the Vector.

CommandItem defaultCmd;

Image myIcon = ImageFactory.createImage(Bitmap.getBitmapResource("my_logo.png"));

if(field.equals(emailAddress)){          
    defaultCmd = new CommandItem(new StringProvider("Email Address"), 
                                 myIcon, 
                                 new Command(new DialogCommandHandler()));
}
else {
    defaultCmd = new CommandItem(new StringProvider("Label Field"), myIcon, new Command(new DialogCommandHandler()));
}

items.addElement(defaultCmd);

return items;

In the custom screen, create a command handler by creating a class that extends the abstract CommandHandler class. In execute(), define the functionality that you want to associate with the pop-up menu items. This command handler could be used by any UI component on your screen (for example, full menu items, buttons, and so on). Because canExecute() is not implemented, this command is always executable. In the following code sample, a dialog box appears when the user clicks a pop-up menu item.

class DialogCommandHandler extends CommandHandler
{
    public void execute(ReadOnlyCommandMetadata metadata, Object context)
    {
        Dialog.alert("Executing command for " + context.toString());
    }           
}

Find out more