As I mentioned in my article about Creating a Blackberry Game, I love this mobile phone and writing programs for it. The device has a serious amount of untapped potential. That’s not to say the phone isn’t already a great tool for its intended purposes (I don’t think I could make it without mine these days), but with the capabilities it has, there are a lot of creative ways it could be used for unconventional purposes.
Global Positioning System
One great feature of many modern Blackberrys is the built in GPS. This is an awesome technology for navigation – I don’t have a GPS in the car and my phone has saved my butt on a number of occasions. However, past that, think about the power this really gives. We’re starting to take positioning for granted these days, but the ability to pinpoint your exact location wherever you are is amazingly powerful. And not only for navigation – we have seen a number of very inventive programs popping up lately from trackers that pinpoint a lost/stolen phone, to photo tagging to attach a location to a picture taken. I’ve had lots of conversations with people as well who have great ideas for unique uses of GPSes. We’re definitely not even close to exhausting this functionality in the Blackberry.
Writing a GPS Program
When I first got my phone, I wanted to write a program to make use of the GPS. I decided I’d write a little tracker program, basically to continually read my current coordinates and post them to a website in realtime (that’s the other amazing piece about a Blackberry, the fact that you have an Internet connection whenever in cell range). The website would display these points on a google map, and people could see my current location and where I’d been (and how fast I was going!). It was a fun project, amazingly easy, and worked right off the bat!
Below is a very quick and dirty program to get the job done. It is not meant to be a polished product – it was a quick test, and I present it here as information on how to grab coordinates and upload them to a website. If you decide to make your own project, you’ll want to write the code a little more cleanly and organized – but this should give some tips on how the libraries are used. I’ve added lots of commenting to explain things as I go.
Also – a portion of the GPS code is grabbed from the RIM site I believe, though it was a long time ago and I’m not sure where. No disrespect to any code I’ve copied – if you find the original source, please post it and I’ll credit it.
tracker.java package com.syntheticdreams.tracker; /* This project makes use of many standard javax libraries, especially in reading the GPS. ** The microedition package in javax contains a number of mobile device related libraries, including the ** location package, which has methods specially designed for working with coordinates and ** pulling them from a GPS. The Blackberry supports the use of this package interfacing with its GPS (for ** providers that have not locked the phone. Verizon has, until recently, locked the GPS of many of its models ** from use by third party applications.) The rest of our package importing is mainly for the user interface. */ 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.system.*; import javax.microedition.location.*; import javax.microedition.location.Location.*; import javax.microedition.location.Criteria.*; import javax.microedition.io.*; import java.util.*; // The UiApplication is a class designed for presenting a user interface to the user and maintaining screens on a stack. // See Creating a Blackberry Game - Part 2 for more info (http://www.toniwestbrook.com/archives/71) public class tracker extends UiApplication { // Our main method is always called first, starts the ball rolling public static void main(String[] args) { // Create a new instance of the main "tracker" class, pushes the main screen onto the stack tracker trackerApp = new tracker(); // Enter the event dispatcher to intercept key and trackball events trackerApp.enterEventDispatcher(); } public tracker() { // See startScreen class below, our main screen where the magic takes place. Push it onto the stack so // the user sees it and the instance of the class starts running and processing. pushScreen(new startScreen()); } } // Our only screen to be pushed on the screen stack final class startScreen extends MainScreen { // A timer that will continually poll the GPS Timer updateTimer = new Timer(); // The specific task for our timer where the dirty work takes place TimerTask updateTask = new TimerTask() { // The run method is what is actually run by the timer every time it resets public void run() { LocationProvider lp; // LocationProvider does the actual work of reading coordinates from the GPS Location currentLoc; // Stores component information of our position Criteria cr = new Criteria(); // Settings for the GPS - we can read it at different accuracy levels HttpConnection httpConn; // An HTTP socket connection class to send our results to a webserver String getStr; // I basically set no requirements on any of the horizontal, vertical, or power consumption requirements below. // The distance components are set in meters if you do want to establish accuracy - the less the accuracy, the // quicker and more likely a successful read (I believe). // You can also set power consumption, between low, medium, high (or no requirement) // There are also a number of other settings you can tweak such as minimum response time, if altitude is required, // speed required, etc. It all depends on the exact application you're writing and how specific you need the info to // be. For our purposes, a rough coordinate is good enough. cr.setCostAllowed(true); cr.setHorizontalAccuracy(javax.microedition.location.Criteria.NO_REQUIREMENT); cr.setVerticalAccuracy(javax.microedition.location.Criteria.NO_REQUIREMENT); cr.setPreferredPowerConsumption(javax.microedition.location.Criteria.NO_REQUIREMENT); try { // Get a new instance of the location provider using the criteria we established above. lp = LocationProvider.getInstance(cr); // Now populate our location object with our current location (with a 60 second timeout) currentLoc = lp.getLocation(60); } // If we hit the timeout or encountered some other error, report it. catch(LocationException e) { Dialog.alert("Error getting coordinates"); return; } // If reading the GPS was interrupted, report it catch(InterruptedException e) { Dialog.alert("GPS Interrupted!"); return; } // If we made it here, we got a successful read. I transmit it to a webserver via a simple querystring. try { // I build the querystring here // set the "lat" querystring var with the latitude from getLatitude getStr = "lat=" + currentLoc.getQualifiedCoordinates().getLatitude(); //lon with longitude getStr = getStr + "&lon=" + currentLoc.getQualifiedCoordinates().getLongitude(); // alt with altitude getStr = getStr + "&alt=" + currentLoc.getQualifiedCoordinates().getAltitude(); // vel with speed getStr = getStr + "&vel=" + currentLoc.getSpeed(); // Now I establish an http connection the webserver running a server side script that can read the values from // the querystring and save them to a database. In my case, I had a simple ASP page that wrote them to a MSSQL // database - this database being read by another webpage that printed said coordinates out on a google map. // But you could do the same with PHP, PERL, or any other server side language of your choice. httpConn = (javax.microedition.io.HttpConnection) javax.microedition.io.Connector.open("http://www.yourwebsitehere.com/yourpage.asp?" + getStr); // Just an easy GET with a querystring. httpConn.setRequestMethod(HttpConnection.GET); // Set HTTP values httpConn.setRequestProperty("Connection","close"); httpConn.setRequestProperty("Content-Length","0"); // Make the request (e.g. send the data) httpConn.getResponseCode(); // Close the socket httpConn.close(); } // If there was an error contacting the webserver, post it catch (java.io.IOException e) { Dialog.alert("Error contacting web server"); return; } } }; // Our main screen's constructor public startScreen() { super(); // Set the window's title LabelField title = new LabelField("GPS Tracker", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH); setTitle(title); // Feel free to snazz up your program with your own messages or real time info from the GPS add(new RichTextField("Starting transmission...")); // Add the update task to the update timer, running it starting in 10 milliseconds, and then every // 240000 milliseconds (4 minutes) updateTimer.scheduleAtFixedRate(updateTask, 10, 240000); } // Cleanup on close public boolean onClose() { Dialog.alert("Transmission Ended!"); System.exit(0); return true; } }
Nothing too bad – but very powerful! I hope this helps a bit on the road to making cool GPS applications!