MobileJava MobileUsing Location-Enabled MIDlets for Mobile Navigation

Using Location-Enabled MIDlets for Mobile Navigation content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Location information has become fairly easy to access nowadays, even on mobile devices. The widespread availability of GPS chipsets such as the SiRF chipsets, which are accurate to within a few meters, as well as the significantly lower costs of these products, have contributed to the accessibility. The Location API for J2ME (JSR 179) even makes it very easy for developers to integrate location information into mobile applications.

This article illustrates how to combine JSR 179 and Scalable Vector Graphics (SVG) to provide navigation for a GPS-enabled mobile device. The application will employ the Scalable 2D Vector Graphics API for J2ME (JSR 226) and a MIDlet. As an example, the article provides and refers to a sample NetBeans project for a college “campus navigation” application.

Author’s Note: The content of the article is the view of the author and not that of Wipro Technologies.

Determining the Device Location

You can determine the location of a mobile device in several ways. Mobile-location methods can be based either on a network or a mobile device. In the network-based location method, you have the following options:

  • The Cell-ID method. This method identifies the location of the handset from the Base Transceiver Station (BTS) that the handset is communicating with and the location of that BTS. Its precision is determined by the size of the cell, and it can be quite inaccurate.
  • Enhanced-Observed Time Difference (E-OTD)/Uplink Time Difference of Arrival (U-TDOA)/Observed Time Difference of Arrival (OTDOA) methods. These methods use monitored time differences to locate the mobile device. Their precision depends on the precision of the mobile network’s system time.

In mobile-based location methods, you have GPS (Global Positioning System). GPS is potentially the most accurate method, but it has a couple of drawbacks. First, it consumes a lot of battery power while in use. Second, its performance suffers in canyon environments such as cities, where satellite visibility is intermittent, tall buildings block the GPS signals, and satellite signals are too limited to estimate the position of the user.

The following are the two types of mobile-based location methods for GPS:

  • Assisted Global Positioning Systems (A-GPS). For a mobile device equipped with an A-GPS receiver, the network uses the cell that the mobile device communicates with to locate the GPS satellite. It then sends this location information to the mobile device, which uses it to narrow the satellite searching scope and shorten the searching time.
  • Autonomous GPS. For a mobile device with a full-function GPS receiver, the mobile device obtains the location information itself. It may, however, take some time to get an initial fix on the visible satellites.

Most modern mobile devices that have a mobile GPS chipset and use KVM will support JSR 179. Table 1 lists the main JSR 179 Location API classes.

LocationProviderUsed for the selection of the location provider
CriteriaRepresents a source of the location information, starting point of location request
LocationRepresents the standard set of basic location information. This includes the time-stamped coordinates, accuracy, speed, course, etc.
CoordinatesRepresents coordinates as latitude-longitude-altitude values.
LocationListenerListener that receives update events associated with a particular LocationProvider
ProximityListenerReceives updates based on terminal crossing into a defined radius around a coordinate.
LandmarkThe Landmark class represents a landmark, such as a known location with a name (such as a monument)
LandmarkStoreThe LandmarkStore class provides methods to store, delete and retrieve landmarks from a persistent landmark store.
Table 1. Main JSR 179 Location API Classes

The NetBeans Project

The NetBeans project is provided here for demonstration. After unzipping the project, you can open it in NetBeans (The examples discussed here are from NetBeans IDE 6.5.1). You can test it on the Java Wireless Tool Kit, which comes as part of the NetBeans Mobility Pack.

If you use a Nokia mobile phone, the Nokia PC Suite allows you to deploy the sample MIDlet from the NetBeans environment directly on the phone through a USB cable. Use a similar methodology for mobile phones from other vendors.

The following are screenshots of the running application on an emulator.

Click here for larger image

Figure 1. Map Screen: This capture of the emulator shows the running MIDlet displaying the campus of Brock University.

Click here for larger image

Figure 2. Map Screen Menu: This capture shows the screen menu for the campus navigation with zoom in and zoom out facility.

Click here for larger image

Figure 3. Zoomed Map Screen: This capture shows the zoomed campus.

The Sample SVG File

A sample SVG file, which is used by the MIDlet, invokes the Campus JPEG file from a web server. For testing with the Java Wireless Tool Kit emulator, the web server can be hosted on the development machine that runs NetBeans.

The SVG file first defines the DTD and the SVG Tiny version used by the mobile device (SVG Tiny 1.2 in this case). The SVG size and the image size are then defined, and the image definition is linked to the URL of the image on the web server. Finally, lines are defined vertically and horizontally to form a grid for ease of location (see Listing 4, which defines the image and its location, as well as the grid for the mobile display of the campus).

Implementing the Location API

To determine location by finding the current latitude and longitude, you have to declare a class that is runnable and also a listener. Runnable is required because you want the instantiated class to be a thread that is constantly running, so it can get updates of the user’s current position and send them to the application. The application will use the updates to reposition the coordinates on the screen map. The listener functionality is added because whenever there is a location change, the listener will automatically be notified.

The declaration of the class called LocPos in the sample NetBeans project for this article is:

public class LocPosition implements Runnable, LocationListener {
You first need a LocationProvider object and a Location object to store the latitude and longitude. After declaring these objects, you have to establish the criteria for getting the location from the LocationProvider (through the satellites). The following code snippet does this:
Location loc;LocationProvider provider= nulltry { Criteria crit = new Criteria(); crit.setCostAllowed(true); //default value crit.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT);     /*Filling up default values required for Criteria before getting instance of Location Provider */  provider = LocationProvider.getInstance(crit);        } catch (LocationException ex) {   ex.printStackTrace();      }
Then you initialize the LocationListener for the provider object obtained:
provider.setLocationListener(this,-1,-1,-1); /*setting up the location listener with default values so that locationUpdated() function 
is called when there is a change in location */
Once the LocationProvider is initialized, you also need to implement the locationUpdated method, which will be invoked by the listener process every time a change in location occurs. Because this method is triggered only when a location change occurs, it gets the coordinates from the Location object and locPos. It also gets the time stamp of the reading, as shown in this code snippet:
public void locationUpdated(LocationProvider provider, Location locPos) {     /*  Updating of latitude, longitude, and time when 
locationUpdated() is called on change of location */ coordinates = locPos.getQualifiedCoordinates(); sb.delete(0,sb.length()); sb.append(new Date(locPos.getTimestamp()).toString()); latitude = coordinates.getLatitude(); longitude = coordinates.getLongitude(); }
The full listing of is available in Listing 1. implements all the features for initializing the location provider and getting the updates of the new position in the listener process when changes to location occur.

Implementing the SVG API

SVG is an XML grammar for rich, dynamic 2D graphics. It boasts the following attributes:
  • Lightweight: SVG graphics are typically more compact than their raster equivalents.
  • Zoomable: SVG content can be viewed at different resolutions (e.g., enlarged or shrunk) without losing quality. This is the reason for including “Scalable” in the name Scalable Vector Graphics.
  • Searchable: Because SVG content is XML, the content of an SVG image is searchable for text elements, comments, or any meta-data.
  • Structured: SVG’s structure makes it suitable to the requirements of user accessibility.

Table 2 provides the various classes and interfaces available in JSR 226: Scalable 2D Vector Graphics API for J2ME, which are used to implement SVG functionality.

Class or InterfaceDescription
Scalable GraphicsFundamental class for 2D rendering
SVGAnimatorClass handles automatic rendering of updates and animations in an SVGImage to a target user interface component
SVGEventListenerInterface used to forward platform-specific events to an application
SVGImageClass represents an image conforming to W3C SVG Tiny 1.1 (1.2) Profile
External Resource HandlerInterface is used to load synchronously any external resources needed for loading SVG content
SVGAnimationElementInterface represents an animation element and includes methods to control timing of animations
SVGElementInterface represents an SVG element in the document tree
SVGLocatableElementInterface represents a drawable SVG element (typically a shape, image, or text)
SVGMAtrixInterface represents an SVG matrix data type identified by an affine transformation equivalent to a linear transformation followed by a translation
SVGPathInterface represents a SVG path data type used to define path geometry
SVGPointInterface represents a SVG point data type identified by its X and Y components
SVGRectInterface represents a SVG rectangle data type consisting of mimimum X, minimum Y, width and height values
SVGRGBColorInterface represents a SVG RGB color data type composed of red, green, and blue componets
SVGSVGElementInterface represents an element in SVG document tree (Whereas SVGElement represents a SVG element in the document tree.)
Table 2. Classes and Interfaces in JSR 226

In the sample NetBeans project for this article, the Canvas used for displaying the SVGImage of the campus layout is a class derived from Canvas called GameCanvas. This is used because the Game Keys can be utilized for positioning the image. The zoom in and zoom out functions in the image displayed in the GameCanvas are achieved with the JSR 226 SVG classes shown in Table 2.

The following gets the root SVG element in the SVG document tree into myEl. From the getBBox() function (BBox stands for bounding Box), you can get the height and width of the SVG root object.

SVGSVGElement myEl = (SVGSVGElement)(
svgImage.getDocument().getDocumentElement());SVGRect myRect = myEl.getBBox();
You can get the current scaling factor by using the getCurrentScale() method of the root SVGElement. Similarly, you can get the current translate position using the getCurrentTranslate() method.
float fa =  myEl.getCurrentScale();SVGPoint   p1= myEl.getCurrentTranslate();
To zoom in, you can multiply the current scale by a factor. This example uses 1.2. The setCurrentScale() method is used for setting the scale. For zoom out, you multiply current scale by a factor of 1/1.2.

This scaling is carried out with respect to the top-left corner, whose coordinates are (0,0). In order to zoom in and out with respect to the center of the display, a translation has to be applied after scaling (as the code will show shortly). To achieve this translation, the SVGPoint p1 obtained from the getCurrentTranslate() method shown above is used to get the X and Y coordinates of the current translated position, as shown below.

float xf = p1.getX();float yf  = p1.getY();
Then the setX() and setY() methods are used to change the translation coordinates, where delta_x and delta_y are the X and Y coordinates by which the current position must be translated.
p1.setX(xf + delta_x);p1.setY(yf + deltay);
Listing 2 shows the code for the complete functionality in The code is for the Canvas UI, the display of the campus map on the screen, and the zoom in, zoom out, and translation functions.

Implementing the MIDlet

Every MIDlet must have a startApp() method to initialize the MIDlet application, a pauseApp() method to pause it, and a destroyApp() method to terminate the MIDlet. The class SVGMidlet extends the MIDlet class and implements a CommandListener interface.

In the startapp() method of the MIDlet in this example, you instantiate a TextBox and pass it when creating a new instance of the Location object, LocPos. This TextBox is used to display the current latitude, longitude, and time of the mobile device. Then the back command is added to the TextBox.

A new thread is started with the LocPos object in a try/catch construct. This thread will constantly update the TextBox with the current latitude and longitude, as well as the time stamp.

Next, the main MIDlet menu items are generated by getList(). The main menu has three items:

  • Get Location: When invoked, Get Location displays the TextBox with the current location and the time constantly updated.
  • See Campus: See Campus is for seeing the map of the campus and the user’s position, as well as the zoom in/zoom out and translation features.
  • Exit: Exit is for exiting from the MIDlet.

The getList() method returns a list of these three items. In the startApp() method, disp.setCurrent(getList()) will display the list of three items by making the Displayable List object the current display on the screen. If GetLocation is invoked, the listAction() method will set the current display to the TextBox and display the location and time with date.

If the user selects See Campus, the corresponding listAction() code will be invoked. This code will start a new SVGStatic Canvas thread, which will get its position updated from the LocPos thread, and implement the zoom and translation features in the campus map used.

If the user exits from the See Campus function, then the SVGStatic Canvas thread is made null before going back to the main menu of the three items (Get Location, See Campus, and Exit).

The pauseApp() and destroyapp() methods are left blank, but you can incorporate any functionality as needed.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories