×
Namespaces

Variants
Actions

How to get Location Using Location API JSR 179

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to retrieve the device's current location with the Location API (JSR-179) on GPS enabled devices. JSR-179 is integrated in Nokia's SDKs, so it is not necessary to add it to the working project as a separate library.

Contents

Device Requirements

The Location API has been introduced on Symbian devices since S60 3rd Edition and on Series 40 devices since Series 40, 6th Edition.

Note that, when trying to identify the devices that support the Location API, it is not enough to look for those with a GPS receiver. A device could provide support for the Location API, even though it is not GPS enabled with the following ways:

  1. An external Bluetooth GPS module can be connected to the device
  2. A network based location retrieval can be used, by identifying the network's cell associated with the device. More information regarding cell ID location retrieval can be found here.

For a complete list of devices that support the Location API, please consult the following table:

JSR-179 version Supported Devices
1.0 List of Devices
1.0.1 List of Devices
1.1 List of Devices

This article describes how to to find information related to the device's current location, by using GPS enabled devices.

Implementation Steps

The location retrieval is a process that includes the following steps:

  1. Setting the criteria for the location inquiry that might include additional requirements such as speed, course or altitude retrieval. The criteria can further restrict the expected horizontal and vertical accuracy of the retrieved pair of coordinates-altitude to certain values.
  2. Getting a Location Provider based on criteria set in the previous step. If the device does not have a build-in GPS receiver, this will cause the device to query for an external GPS module. Even if the device does have a build-in GPS receiver, getting the location provider may fail because the criteria cannot be satisfied by the given device. It is therefore important, to catch any exceptions that might be thrown at this step.
  3. Associating a Location Listener object to the Location Provider. The Location Listener interface provides the means to set the frequency of the location retrieval intervals, as well as a time out value, i.e. how late the location update is allowed to come, and a maxAge value which indicates how long the retrieved location should be valid, so that it can be re-used. Setting the interval, time out and maxAge values to -1, assigns the default values for the given provider. Depending on what the purpose of the application is, and how often, the location updates are needed, these values can be modified.
  4. Listening for Location Updates and getting the location object by using the locationUpdated() method.

Implementing the LocationMIDlet

The MIDlet starts with a form, where the user can specify the criteria for the retrieval of the location provider. By selecting the "Get" option, the next screen provides the location information based on the set of criteria specified in the previous step. It is easy to step back, assign another set of criteria and see how the device responds. Restricting too much the criteria will eventually display an error alert. The application only displays whether any extra information regarding the current location is available or not. If available, further parsing is needed, according to the NMEA specification.

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
 
public class LocationMIDlet extends MIDlet implements CommandListener, LocationListener,Runnable {
 
Thread t;
Criteria criteria;
LocationProvider lp;
Form f;
Display display;
ChoiceGroup speedNcourse;
ChoiceGroup cost;
ChoiceGroup power;
ChoiceGroup altitude;
TextField haccuracy;
TextField vaccuracy;
TextField responsetime;
 
StringItem latitudeString;
StringItem longitudeString;
StringItem altitudeString;
StringItem courseString;
StringItem speedString;
StringItem haccuracyString;
StringItem vaccuracyString;
StringItem extraInfoString;
 
Command exitCommand=new Command("Exit", Command.EXIT,0);
Command getLocation=new Command("Get",Command.OK,1);
Command backCommand=new Command("Back", Command.OK,2);
 
protected void startApp() throws MIDletStateChangeException {
f=new Form("");
criteria=new Criteria();
display=Display.getDisplay(this);
//displays the criteria form
displayCriteriaForm(1,0,3,1,0,0,0);
}
public void run()
{
try{
setCriteria();
lp = LocationProvider.getInstance(criteria);
lp.setLocationListener(this, -1, -1, -1);
displayLocationForm();
}catch(Exception e)
{
Alert alert = new Alert("Error", "Could not retrieve location for the given criteria!", null, AlertType.ERROR);
display.setCurrent(alert);
}
}
public void displayCriteriaForm(int speedcoursearg,int costarg,int powerarg,
int altitudearg,int horizontalarg,int verticalarg,int responsearg)
{
f.setTitle("Set Criteria");
 
speedNcourse=new ChoiceGroup("Speed and Course:",ChoiceGroup.EXCLUSIVE);
speedNcourse.insert(0, "Yes", null);
speedNcourse.insert(1, "No", null);
speedNcourse.setSelectedIndex(speedcoursearg, true);
f.append(speedNcourse);
 
cost=new ChoiceGroup("Allow charges:",ChoiceGroup.EXCLUSIVE);
cost.insert(0, "Yes", null);
cost.insert(1, "No", null);
cost.setSelectedIndex(costarg,true);
f.append(cost);
 
power=new ChoiceGroup("Power Consumption:",ChoiceGroup.EXCLUSIVE);
power.insert(0, "Low", null);
power.insert(1, "Medium", null);
power.insert(2, "High", null);
power.insert(3, "Not Required", null);
power.setSelectedIndex(powerarg, true);
f.append(power);
 
altitude=new ChoiceGroup("Altitude:",ChoiceGroup.EXCLUSIVE);
altitude.insert(0, "Yes", null);
altitude.insert(1, "No", null);
altitude.setSelectedIndex(altitudearg, true);
f.append(altitude);
 
haccuracy=new TextField("H.Accuracy(m),0=No Req:",""+horizontalarg,3, TextField.NUMERIC);
 
vaccuracy=new TextField("V.Accuracy(m),0=No Req:", ""+verticalarg, 3, TextField.NUMERIC);
f.append(haccuracy);
f.append(vaccuracy);
 
responsetime=new TextField("Time Out(ms),0=No Req:",""+responsearg, 5, TextField.NUMERIC);
f.append(responsetime);
 
f.addCommand(exitCommand);
f.addCommand(getLocation);
f.setCommandListener(this);
display.setCurrent(f);
 
}
public void displayLocationForm()
{
f.deleteAll();
f.setTitle("Location info");
f.removeCommand(getLocation);
f.addCommand(backCommand);
latitudeString=new StringItem("Latitude:","N/A");
longitudeString = new StringItem("Longitude:","N/A");
altitudeString= new StringItem("Altitude:","N/A");
courseString=new StringItem("Course:","N/A");
speedString=new StringItem("Speed:","N/A");
haccuracyString=new StringItem("Horizontal Accuracy:","N/A");
vaccuracyString=new StringItem("Vertical Accuracy:","N/A");
extraInfoString=new StringItem("Extra Info:","N/A");
 
f.append(latitudeString);
f.append(longitudeString);
f.append(altitudeString);
f.append(courseString);
f.append(speedString);
f.append(haccuracyString);
f.append(vaccuracyString);
f.append(extraInfoString);
}
public void updateForm(String latitudevalue,String longitudevalue,String altitudevalue,String coursevalue,String speedvalue,
String haccuracyvalue,String vaccuracyvalue, String extrainfovalue)
{
latitudeString.setText(latitudevalue);
longitudeString.setText(longitudevalue);
altitudeString.setText(altitudevalue);
courseString.setText(coursevalue);
speedString.setText(speedvalue);
haccuracyString.setText(haccuracyvalue);
vaccuracyString.setText(vaccuracyvalue);
extraInfoString.setText(extrainfovalue);
}
public void locationUpdated(LocationProvider arg0, Location loc)
{
String latitudevalue="N/A";
String longitudevalue="N/A";
String altitudevalue="N/A";
String coursevalue="N/A";
String speedvalue="N/A";
String haccuracyvalue="N/A";
String vaccuracyvalue="N/A";
String extrainfovalue="N/A";
if(loc.isValid())
{
QualifiedCoordinates c = loc.getQualifiedCoordinates();
latitudevalue=String.valueOf(c.getLatitude());
longitudevalue=String.valueOf(c.getLongitude());
 
if(criteria.isAltitudeRequired())
altitudevalue=String.valueOf(c.getAltitude());
 
if(criteria.isSpeedAndCourseRequired())
{
float currentCourse=loc.getCourse();
float currentSpeed=loc.getSpeed();
coursevalue=String.valueOf(currentCourse);
speedvalue=String.valueOf(currentSpeed);
}
 
float haccuracyvalueInFloat=c.getHorizontalAccuracy();
float vaccuracyvalueInFloat=c.getVerticalAccuracy();
haccuracyvalue=String.valueOf(haccuracyvalueInFloat);
vaccuracyvalue=String.valueOf(vaccuracyvalueInFloat);
//Any extra Info for this location should be parsed according
//to the NMEA Specifications.
extrainfovalue=loc.getExtraInfo("application/X-jsr179-location-nmea");
 
if(extrainfovalue==null)
extrainfovalue="N/A";
else
extrainfovalue="Available in NMEA format!";
}
updateForm(latitudevalue,longitudevalue,altitudevalue,coursevalue,speedvalue,haccuracyvalue,vaccuracyvalue,
extrainfovalue);
}
public void setCriteria()
{
 
switch (speedNcourse.getSelectedIndex())
{
case 0: criteria.setSpeedAndCourseRequired(true); break;
case 1: criteria.setSpeedAndCourseRequired(false); break;
}
switch (cost.getSelectedIndex())
{
case 0: criteria.setCostAllowed(true); break;
case 1: criteria.setCostAllowed(false); break;
}
switch (power.getSelectedIndex())
{
case 0: criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_LOW); break;
case 1: criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_MEDIUM); break;
case 2: criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH); break;
case 3: criteria.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT); break;
}
switch (altitude.getSelectedIndex())
{
case 0: criteria.setAltitudeRequired(true); break;
case 1: criteria.setAltitudeRequired(false); break;
}
criteria.setHorizontalAccuracy(Integer.parseInt(haccuracy.getString()));
criteria.setVerticalAccuracy(Integer.parseInt(vaccuracy.getString()));
 
criteria.setPreferredResponseTime(Integer.parseInt(responsetime.getString()));
}
public void commandAction(Command c, Displayable d)
{
if (c == exitCommand) {
notifyDestroyed();
}
 
if(c==getLocation)
{
t=new Thread(this);
t.start();
}
if(c==backCommand)
{
f.deleteAll();
f.removeCommand(backCommand);
int sp=speedNcourse.getSelectedIndex();
int co=cost.getSelectedIndex();
int p=power.getSelectedIndex();
int a=altitude.getSelectedIndex();
int ha=Integer.valueOf(haccuracy.getString()).intValue();
int va=Integer.valueOf(vaccuracy.getString()).intValue();
int rt=Integer.valueOf(responsetime.getString()).intValue();
 
displayCriteriaForm(sp,co,p,a,ha,va,rt);
}
}
public void providerStateChanged(LocationProvider arg0, int arg1) {}
 
protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {}
protected void pauseApp() {}
}

Source and Binary Files

The code above can be downloaded from File:LocationMIDletSource.zip

The installation .jar and .jad files can be downloaded from File:LocationMIDletBinaries.zip

See also

JSR-179 API at Nokia's online Java Developer's Library


Article Metadata
Code ExampleTested with
Devices(s): 6700 classic, Nokia 701
Compatibility
Platform(s): since Series 40 6th Edition, since S60 3rd Edition
Symbian
Device(s): GPS enabled devices
Article
Keywords: Location, GPS, coordinates, course, speed, altitude, latitude, longitude
Created: skalogir (22 Nov 2011)
Reviewed: skalogir (22 Nov 2011)
Last edited: hamishwillee (26 Jun 2013)
This page was last modified on 26 June 2013, at 08:23.
139 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×