Highly contextualized

A typical BlackBerry® device application performs a task in response to user input. If the application needs additional information to perform the task, the application queries the user for that information. A well-designed, typical application might store information so it doesn't have to ask for the information again. But a Super App is designed to avoid querying its users at all. Instead, a Super App tries to gather the information it needs programmatically.

Access to a GPS radio, an accelerometer, comprehensive APIs for gathering BlackBerry device information, APIs for using core BlackBerry application functionality, and reliable connectivity to a wide variety of web services—with these features, a Super App can gather much of the contextual information it requires.

A typical application might perform a task at a scheduled time, but a typical application doesn't often initiate tasks. A Super App with more information about the context it is running in, can initiate appropriate tasks and present users with appropriate features and options at the right time. With a Super App, you can surprise your users. Sometimes a Super App almost appears to be intelligent.

The Clock application on a BlackBerry device includes a great example of a simple, highly contextualized feature. When you travel between time zones, the Clock application offers to reset your home time zone to the zone that you have travelled into. This feature improves the application in two ways. First, you are reminded to update your time zone. And second, you are presented with the correct time zone. You only have to press a button to confirm that you want the Clock application to make the change.

What are the benefits of a highly contextualized application?

  • Improve the user experience. Applications that anticipate user needs and prompt users to verify input might be easier to use than applications that do not anticipate user needs and require users to input information from scratch.
  • 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 application highly contextualized by using any of the following approaches.

Approach

Examples

Add location context.

If your application includes a search feature, the feature can probably be improved by automatically incorporating the current location of the BlackBerry® device into the search criteria. Users searching for gas stations are likely most interested in ones near their current location. Many web services provide location-specific services. Your Super App can use those services.

Add time context.

Imagine you create an application that can search for restaurants. You can add some context by using the location of the device to organize the search results by distance from the device. If the data service you use includes information about hours of operation, you can make the results even better by only showing restaurants that are open. The data service might even include information about lunch or dinner specials and, taking into context the current time, you could present the results accordingly.

Add date context.

Some web sites and applications display custom themes to celebrate special days such as holidays, birthdays of famous people, or current events. This customization is an example of how you can improve an application with a minor tweak that makes use of context. In this case, the context is the date.

Your Super App should customize its actions according to the current date when doing so could improve the user experience.

Add battery level context.

Your Super App should 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 connectivity context.

Your Super App should check the type of network connections that are available. For example, if the user requests that the application download and play a large video file when the device is roaming on a wireless network, the application should warn the user that the download might be expensive. A Super 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 application should warn the user that the download might take a very long time. The application might provide an approximate download time, and let the user decide whether to proceed.

Add device characteristics context.

Your Super App should adapt to the device model it is running on. Battery life and connectivity are universal contexts for BlackBerry device applications. 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.

Super Apps provide good default choices for their users. For example, on a device with a touch screen that supports gestures, a Super App displays hints about how to zoom in and out using pinch gestures.

Use contextual menus.

Your Super 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.

Adding connectivity context

Super Apps are designed to take into account the BlackBerry® device models that they run on and the variable levels of connectivity. Super Apps are also designed to take into account different types of connections with different associated costs. Often, Wi-Fi® connections are cheap, and roaming cellular connections are expensive.

Your application 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 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 flag to determine if a device is currently using a roaming cellular connection, as demonstrated in the following code sample.

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 a BlackBerry® device application 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 application to conserve power. When your application receives notification that the battery power level is good again, you can turn on those features again.

To process power level change events, your application 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)
   {
   }
}

BlackBerry device characteristics

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

A BlackBerry® device user can use a BlackBerry device application to access GPS data and view information on the location, speed, and direction of the BlackBerry device. A BlackBerry device application 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, a BlackBerry device application invokes 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. A BlackBerry device application invokes Criteria.setCostAllowed(true) to use a source of GPS data that costs money to use. The BlackBerry device application 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.

A BlackBerry device application sets the properties of the Criteria object to specify the mode the application uses to retrieve GPS data. The cell site mode allows a BlackBerry device application to retrieve GPS data from a cell site tower. This mode is faster but less accurate than other modes. The assisted mode allows a BlackBerry device application 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 a BlackBerry device application to retrieve GPS data from the BlackBerry device. This mode is slower but more accurate than other modes.

After creating and setting the properties of the Criteria object, a BlackBerry device application invokes javax.microedition.location.LocationProvider.getInstance(Criteria) using the Criteria object as a parameter to retrieve a LocationProvider object. A BlackBerry device application 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 BlackBerry device.

A BlackBerry device application can listen for updates from a source for GPS data to provide a BlackBerry device user with current GPS information. The BlackBerry device application 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 BlackBerry device application checks for new GPS data.

Retrieve the location of a BlackBerry device

  1. Import the required classes.
    import javax.microedition.location.*;
  2. Create a class and a constructor.
    public class handleGPS
    {
       public handleGPS()
       {
       }
    }
  3. Declare static fields in the class.
    static GPSThread gpsThread;
    static double latitude;
    static double longitude;
  4. In the constructor, create and start a local thread.
    gpsThread = new GPSThread();
    gpsThread.start();
  5. In the class, create a private class that extends Thread, and create a run() method.
    private class GPSThread extends Thread
    {
       public void run()
       {
       }
    }
  6. In the run() method, create an instance of the Criteria class. Invoke setCostAllowed(false) to specify that the autonomous mode.
    Criteria myCriteria = new Criteria();
    myCriteria.setCostAllowed(false);
  7. 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 application by using the classes provided in the net.rim.device.api.ui.menu package.

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.

Find out more

For more information about pop-up menus and submenus, visit the following resources:

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 application 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.

Create a pop-up menu

  1. 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.*;
  2. Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. The MyPopUpMenuScreen class, which is described in step 3, 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());
        } 
    }
  3. Create the custom screen for the application 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");
        }
    }
  4. 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());
  5. 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);
  6. 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. The ItemProvider class is described in step 7.
    ItemProvider itemProvider = new ItemProvider();
                           
    labelField.setCommandItemProvider(itemProvider);
    emailAddress.setCommandItemProvider(itemProvider);
  7. 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)
        {
        }
    }
  8. 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 the following code sample, 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, which is described in step 9. 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;
  9. 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());
        }           
    }
Next topic: Integrated

Was this information helpful? Send us your comments.