Blackberry GPS/Location API
July 10, 2007 – 1:36 amI just got finished playing with the blackberry Location API. I was pleasently suprised how it easy it was to work with. The key to it is that your phone must be a 4.2 BB OS phone (or upgraded to 4.2 like I did with my8700g) for the Location API to work with BT Pucks. The two source files for a simple application are pasted below the app is call Spot Finder.
Basically what it does is allows you to mark and save a location that you are currently in and then later find your way back to that location. It will give you the distance and direction that you need to go. Could be useful for remember your parking spot or the location of a bar you need to get back to. Unfortately in my basic testing its accurate but not that accurate. It’s not perfect but it is a interesting little application especially for learning the basics of the blackberry Location API.
You can download spot finder here.
Java Source:
/* Spot Finder.java */
package com.apsquared.spotfinder;import java.util.Enumeration;
import javax.microedition.lcdui.TextField;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.blackberry.api.invoke.*;
import javax.microedition.location.*;public class SpotFinder extends MyApp {
public static void main(String[] args)
{
SpotFinder theApp = new SpotFinder();
//To make the application enter the event thread and start processing messages, we invoke the enterEventDispatcher method
theApp.enterEventDispatcher();
}
MainScreen theMainScreen = null;
RichTextField spotLocation = null;
RichTextField currentLocation = null;
RichTextField introMsg = null;
RichTextField directions = null;
String storeName = "SPOT";
double spotLat;
double spotLong;
double curLat;
double curLong;
public SpotFinder()
{
theMainScreen = createMainScreen();
pushScreen(theMainScreen);
}
private MainScreen createMainScreen()
{
//Create a new screen for the applicatin
MainScreen screen = new MainScreen();
screen.addKeyListener(this);
screen.addTrackwheelListener(this);
introMsg = new RichTextField("Welcome to Spot Finder!");
spotLocation = new RichTextField("Current Spot: ");
currentLocation = new RichTextField("Current Location: ");
directions = new RichTextField("");
screen.add(introMsg);
screen.add(spotLocation);
screen.add(currentLocation);
screen.add(directions);
//Add a field to the title region of the screen. We use a simple LabelField here. The ELLIPSIS option truncates
// the label text with "..." if the text was too long for the space available.
screen.setTitle(new LabelField("Spot Finder", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));
return screen;
}
public void setDirections(final String locStr)
{
UiApplication.getUiApplication().invokeLater (new Runnable() {
public void run()
{
directions.setText(locStr);
}});
}
public void setIntroMsg(final String locStr)
{
UiApplication.getUiApplication().invokeLater (new Runnable() {
public void run()
{
introMsg.setText(locStr);
}});
}
public void setCurLocation(double lat, double lng, float course, float speed)
{
curLat = lat;
curLong = lng;
String latLong = new String(curLat+" "+curLong);
setCurLocation(latLong);
//TODO: check for valid spot
Coordinates from = new Coordinates(curLat,curLong,0);
Coordinates to = new Coordinates(spotLat,spotLong,0);
float dist = from.distance(to) * (float)3.2808399 ;
//i think calculation should be azimuth - course (+360 if value is neg)
float dir = from.azimuthTo(to) - course;
if (dir<0)
dir+=360;
setDirections("Distance: "+dist+" ft.\nDirection: "+dir);
}
public void setCurLocation(final String locStr)
{
UiApplication.getUiApplication().invokeLater (new Runnable() {
public void run()
{
currentLocation.setText("Current Location:\n"+locStr);
}});
}
public void setSpot(double lat, double lng)
{
spotLat = lat;
spotLong = lng;
String latLong = new String(spotLat+" "+spotLong);
setSpot(latLong);
}
public void setSpot(final String locStr)
{
UiApplication.getUiApplication().invokeLater (new Runnable() {
public void run()
{
spotLocation.setText("Current Spot:\n"+locStr);
}});
}
public void msgBox(final String msg)
{
UiApplication.getUiApplication().invokeLater (new Runnable() {
public void run()
{
Dialog.alert(msg);
}});
}
protected void makeMenu(Menu menu, int instance)
{
Field focus = UiApplication.getUiApplication().getActiveScreen().getLeafFieldWithFocus();
if(focus != null) {
ContextMenu contextMenu = focus.getContextMenu();
if( !contextMenu.isEmpty()) {
menu.add(contextMenu);
menu.addSeparator();
}
}
MenuItem markSpot = new MenuItem("Get Current Spot",50,8) {
public void run()
{
markSpot();
}
};
MenuItem saveSpot = new MenuItem("Save Current Spot",50,8) {
public void run()
{
saveSpot();
}
};
MenuItem loadSpot = new MenuItem("Load Current Spot",50,8) {
public void run()
{
loadSpot();
}
};
MenuItem findSpot = new MenuItem("Find Current Spot",50,8) {
public void run()
{
findSpot();
}
};
menu.add(markSpot);
menu.add(saveSpot);
menu.addSeparator();
menu.add(loadSpot);
menu.add(findSpot);
}
private void saveSpot()
{
LandmarkStore lStore = LandmarkStore.getInstance(storeName);
if (lStore == null)
{
try
{
LandmarkStore.createLandmarkStore(storeName);
}
catch (Exception e)
{
msgBox("Error creating store. "+e.toString());
return;
}
}
try
{
lStore = LandmarkStore.getInstance(storeName);
Enumeration e = lStore.getLandmarks();
Landmark lMark = null;
if (e!=null && e.hasMoreElements())
{
lMark = (Landmark) e.nextElement();
lMark.setQualifiedCoordinates(new QualifiedCoordinates(spotLat,spotLong,0,Float.NaN, Float.NaN));
}
else
{
lMark = new Landmark("SPOT1","SPOT1",new QualifiedCoordinates(spotLat,spotLong,0,Float.NaN, Float.NaN),null);
}
lStore.addLandmark(lMark, null);
msgBox("Spot Saved!");
}
catch (Exception e)
{
msgBox("Error saving spot. "+e.toString());
}
}
private void loadSpot()
{
LandmarkStore lStore = LandmarkStore.getInstance(storeName);
if (lStore == null)
{
msgBox("No store to open.");
return;
}
try
{
lStore = LandmarkStore.getInstance(storeName);
Enumeration e = lStore.getLandmarks();
while (e.hasMoreElements())
{
Landmark lMark = (Landmark) e.nextElement();
setSpot(lMark.getQualifiedCoordinates().getLatitude(),lMark.getQualifiedCoordinates().getLongitude());
break;
}
}
catch (Exception e)
{
msgBox("Error saving spot. "+e.toString());
}
}
private void findSpot()
{
try
{
LocationProvider lPvd = LocationProvider.getInstance(new Criteria());
lPvd.setLocationListener(new MyLocationListener(this,false), 5, 5, 5);
}
catch (Exception e){
setIntroMsg("Error setting up location listener:\n"+e.toString());
}
}
private void markSpot()
{
try
{
LocationProvider lPvd = LocationProvider.getInstance(new Criteria());
lPvd.setLocationListener(new MyLocationListener(this,true), 1, 1, 1);
}
catch (Exception e)
{
setIntroMsg("Error getting location:\n"+e.toString());
}
}
//empty - nothing to do on exit
protected void onExit() {
}
}
/* MyLocationListener */
package com.apsquared.spotfinder;
import javax.microedition.location.*;
public class MyLocationListener implements LocationListener {
SpotFinder sf;
boolean onceOnly;
public MyLocationListener(SpotFinder sf, boolean onceOnly)
{
this.sf = sf;
this.onceOnly = onceOnly;
}
public void locationUpdated(LocationProvider provider,
Location location)
{
QualifiedCoordinates qc = location.getQualifiedCoordinates();
if (onceOnly)
{
sf.setSpot(qc.getLatitude(),qc.getLongitude());
provider.reset();
provider.setLocationListener(null, 0, 0, 0);
}
else
{
sf.setCurLocation(qc.getLatitude(),qc.getLongitude(),location.getCourse(),location.getSpeed());
}
}
public void providerStateChanged(LocationProvider provider,
int newState)
{
}
}



9 Responses to “Blackberry GPS/Location API”
Hi thanks for this great code. I am using Netbeans and this works in the emulator. But when I run it on the Blackberry 8800, I get NoClassDefFoundError. I figured that I have to include lapi.jar so I found it on the Nokia site but when I include that in the project I get the LocationException that there are no location providers. It also doesn’t ask for the permissions. Do you include the lapi.jar? How do you make it ask for the permissions?
Thanks!
Josh
By Josh L on Jul 30, 2007
So… here’s my $0.02. This is the essential piece of any gps-driven software. If I could enter destinations, waypoints, etc. easily then I would have the underpinnings of a geocaching program.
By Fred on Jul 31, 2007
I couldn’t understand some parts of this article Blackberry GPS/Location API, but I guess I just need to check some more resources regarding this, because it sounds interesting.
By Daniel on Aug 14, 2007
Hi,
We have a WAP site for mobiles, where we have the search features for yellow page listings (i.e., Business name, Address, Phone number, Description, etc). Now, we planning to establish the location based services (LBS) using GPS.
For example, assume that I am a traveler, visiting Bangalore-India for the first time and standing Trinity Circle (MG Road, Bangalore), using my mobile if I search for list of Pizza corners nearby my location, then the system should respond with the list of Pizza shops nearby my location (and with sort by distance).
Please advice my how I need to achieve this task, and currently am using JSP/ASP for my WAP site. Also advice me how to execute the above code
Best regards,
Arul
By Arul Kumar on Jun 17, 2008
Hi,
thanks… i have a doubt in the above code… can you explain about MyApp and can you give me the complete code of Spot Finder.
I got an error message saying
D:\SpotFinder.java:9: cannot find symbol
symbol: class MyApp
public class SpotFinder extends MyApp{
Thanks in advance!!!
By Prakash on Oct 1, 2008
Hi Arul,
I’m trying to create an application for an ambulance company that will show the dispatcher the location of units based on thier GPS enabled phones.
It sort of soulds like you are doing something like this…
Would you mind sending me your email so I can bounce some ideas off you?
You can reach me at gregg.drennan@gmail.com
Thanks,
Gregg
By Gregg on Oct 28, 2008
Great stuff and easy to follow. Just what I was looking for. Thanks again.
By Karen Wournell on Jan 27, 2009