topics
mobile
data mining
web
data visualization
distributed computing
blackberry, iphone, android
sentiment analysis, string matching
social networking, google app engine
processing
hadoop, aster data
code blackberry storm gps
This example outlines how to get GPS working on a real BlackBerry Storm using Verizon Wireless with GPS and data services enabled.

BLACKBERRY GPS MAINSCREEN
BBTMainScreen is a main screen class that tracks a user's GPS location. The class sends updates every 10 seconds to LOCATION_URL. The most important (and most difficult) part to figure out is how to configure your Criteria and LocationListener. If these aren't configured properly, the Storm will disable its GPS listener temporarily.

Please copy the resetGPS() criteria/location listener settings EXACTLY as they are shown.
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;

import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiEngine;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.MainScreen;
import bbtracker.uitl.BBTHTTPClient;

public class BBTMainScreen extends MainScreen {
	public final static String LOCATION_URL = "YOUR SCRIPT LOCATION";

	private RichTextField logField;
	private String log;
	private long lastGPSRead;

	public BBTMainScreen() {
		log = "";
		setTitle(new LabelField("BBTracker GPS Fix", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));

		ButtonField btn = new ButtonField("follow logs", ButtonField.CONSUME_CLICK);
		btn.setChangeListener(new ButtonListener());
		this.add(btn);
		
		logField = new RichTextField("asdf");
		this.add(logField);
		
		lastGPSRead = System.currentTimeMillis();
		
		new LocationTracker();
	}
	
	public boolean onClose() {
		Application.getApplication().requestBackground();
		
		return false;
	}
	
	final class ButtonListener implements FieldChangeListener {
		public void fieldChanged(Field field, int context) {
			UiEngine ui = Ui.getUiEngine();
			Screen screen = new Dialog(Dialog.D_OK, BBTMainScreen.this.log, Dialog.OK,
			Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION), Manager.VERTICAL_SCROLL);
			ui.queueStatus(screen, 1, true);
		}
	}
	
	class LocationTracker extends TimerTask {
		private double longitude, latitude;
		private Timer timer;
		private LocationProvider provider;
		
		public LocationTracker() {
			timer = new Timer();
			
			resetGPS();
			
			timer.schedule(this, 0, 60000);
		}
		
		public void resetGPS() {
			try {
				if(provider != null) {
					provider.setLocationListener(null, 0, 0, 0);
					provider.reset();
					provider = null;
				}
				
				Criteria criteria = new Criteria();
				
				criteria.setHorizontalAccuracy(1000);
				criteria.setVerticalAccuracy(1000);
				criteria.setCostAllowed(false);
			  
//				criteria.setAltitudeRequired(false);
//				criteria.setSpeedAndCourseRequired(false);
//				criteria.setAddressInfoRequired(false);
				criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_LOW);
				
				provider = LocationProvider.getInstance(criteria);
				provider.setLocationListener(new MyLocationListener(), 10, -1, -1);
				
				// reset the gps counter so we wait another 5 mins before a reset
				lastGPSRead = System.currentTimeMillis();
			} catch(Exception e) { log = e.toString() + log; }
			
			log = "reset gps\n" + log;
		}
		
		public void run() {
			if(log.length() > 3000) {
				log = log.substring(log.length() - 3000);
			}
			
			if(System.currentTimeMillis() - lastGPSRead > 300000) {
				BBTHTTPClient.getPage(LOCATION_URL + "?longitude=-1&latitude=-1");
				resetGPS();
				BBTHTTPClient.getPage(LOCATION_URL + "?longitude=-2&latitude=-2");
			}
			
			log = longitude + "," + latitude + "\n" + log;
			
			BBTMainScreen.this.logField.setText(longitude + "," + latitude + "\n");
			
			log = BBTHTTPClient.getPage(LOCATION_URL + "?longitude=" + longitude + "&latitude=" + latitude).trim() + log;
		}
		
		private class MyLocationListener implements LocationListener {
			public void locationUpdated(LocationProvider provider, Location location)
			{
				if(location != null && location.isValid())
				{
					log = "got valid coords\n" + log;
					
					QualifiedCoordinates qc = location.getQualifiedCoordinates();

					try {
						// TODO: not thread safe (assignment should be done at one time)
						LocationTracker.this.longitude = qc.getLongitude();
						LocationTracker.this.latitude = qc.getLatitude();
						
						lastGPSRead = System.currentTimeMillis();
					} catch(Exception e) { log = e.toString() + log; }
				}
				else
				{
					log = "location is not valid..\n" + log;
				}
			}

			public void providerStateChanged(LocationProvider provider, int newState) {
				// TODO: if provider was disabled, then disable reporting
				log = "state changed: " + newState + "\n" + log;
				
				LocationTracker.this.resetGPS();
				
//				try {
//					provider.setLocationListener(null, 0, 0, 0);
//					provider.reset();
//					provider = null;
//					provider = LocationProvider.getInstance(new Criteria());
//					provider.setLocationListener(new MyLocationListener(), 10, -1, -1);
//				} catch(Exception e) { log = e.toString() + log; }
			}
		}
	}
}
SIGNING YOUR CODE
If you run the above code on your BlackBerry Storm, you will get a "GPS not allowed" LocationProvider exception. You need to get your code signed if you want to use the BlackBerry Storm with GPS in your app. To do this, you need to buy a $20 certificate from RIM.

After you get your certificate, you need to sign your .cod file using "Signature Tool". Before you do this, you need to change your .csi file. For some reason, BlackBerry does not properly configure the .csi file to include ALL requirements. It took me a long time to figure this out. Your .csi file should look like this.
33000000=RIMAPPSA2
52424200=RIM Blackberry Apps API
52434300=RIM Crypto API - Certicom
52434900=RIM Crypto API - Internal
52435200=RIM Crypto API - RIM
52525400=RIM Runtime API
TESTING
After your code is signed, you can put it on to your BlackBerry, and run it. Running the code should show you your long/lat. If it gives you 0/0, or -1/-1 at first, wait for a minute or two. Resolving the GPS location can take a minute.

LINKS
My Last BlackBerry GPS Post
My BlackBerry Support Forum Post
blog comments powered by Disqus