Creating a Blackberry GPS Tracker

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!

36 Responses to Creating a Blackberry GPS Tracker

  1. Richard says:

    hallo, as I am not a programmer, this is difficult for me to read.
    What I am searching for is to convert my blackberry to a GPS logger.
    I am thinking to put this function on at the start of my holiday and at the end I will receive a log file with all the GPS data of the last weeks (resolution 1 or 2 minutes).
    Can your program do such a thing or do you know a free program which can do this?

    Many thanks

  2. Cliff says:

    Toni,

    This has been the exact program I have been looking for. When I run it on my Blackberry 8830 the program hangs displaying “Starting transmission…”. When I run it in the BlackBerry Simulator I get NullPointerException on line:

    currentLoc = lp.getLocation(60);

    Any ideas?
    Thanks for posting this program.

  3. Toni says:

    Richard – this is mainly directed toward programmers, so if you don’t have much experience in development, it would definitely be a good idea to snag one already made. I don’t know of any specific ones, but I tried googling “blackberry gps logger” and did find one mentioned, you might want to check that one out.

    Cliff – are you using a Verizon BB 8830? I know until recently they didn’t open up the GPS functionality to third party applications, which would probably cause it to freeze up like that – I think Verizon released a new official version of the OS that might allow third party use. If you don’t have a Verizon let me know. As for the simulator, I’m not sure how it exports the virtual GPS or if the attributes specified for Horizontal/Vertical Accuracy/Power Consumption etc are the same, so I wouldn’t rely on it too much.

  4. Jeremy says:

    I am using the BB Simulator and I keep getting a NullReferenceException is there any update to this code?

  5. Jeremy says:

    I keep getting an “Error Getting Coordinates” and I don’t know where to go from there. Is there any way to view it in more details?

  6. Toni says:

    HI Jeremy -

    From the comments above, it appears that the NullReferenceException is caused by running it on the simulator. When I wrote this code I tested it out strictly on a real Blackberry so I didn’t run into it. Are you getting the “Error Getting Coordinates” on a simulator or real BB? If a real Blackberry, what carrier and model is it?

  7. Toni says:

    Also, if you’re using a real blackberry, make sure you’re actually in an area that can get a GPS sync (like next to a window or outside). If you’re inside where it can’t contact any satellites, it won’t be able to get any coordinates.

  8. Jeremy says:

    I’m using it on the 8530i simulator, but it should work when you inject the GPS in through the simulator right?

  9. Toni says:

    I’m not sure honestly, I haven’t tried it through the simulator, but I do know from the other comments that people using the simulator have run into similar errors. I would at least try it on a real Blackberry to see if the result is the same first, it may not be a code issue, it may be a simulator issue. Let me know how it goes, I’d be curious!

  10. Dave Thomas says:

    Toni, first off you are pure uber mega awesome as until now I had no idea how to make JAVA work (Ok so I did sort of but I like VB.NET way to much)… in any case, is there anyway you could send me the server side app that runs this? Or possibly post somewhere? Maybe even the solution file with ommited IP addresses and so forth? Maybe just a personal email??? Ohhh you would be soooo cooool!

  11. Jeremy says:

    Dave, here is what I used, this may help you…

    The link would look something like this:
    http://www.MYDOMAIN.com/connecttodb.php?lat=20.1234&long=30.4321&alt=50&name=John

    And here is the PHP code that runs it all, you should be able to change some stuff around to get it to work.

  12. Dave Thomas says:

    Jeremy, thanks so much for the URL… did you forget to post the PHP code?

  13. Jeremy says:

    No, it deleted it… I’ll take out the opening and closing tags and try that….

    //Connect to the DB
    $link = mysql_connect(‘MYSQL.MYDOMAIN.COM’, ‘MYUSERNAME’, ‘MYPASSWORD’);
    if (!$link) {
    die(‘Could not connect: ‘ . mysql_error());
    }
    echo ‘Connected successfully’;
    mysql_select_db(MYDBNAME);

    //Get the variables from the URL path
    $lat = $_GET['lat'];
    $long = $_GET['long'];
    $alt = $_GET['alt'];
    $name = $_GET['name'];

    //This is for debugging purposes
    //echo $lat . “\n”;
    //echo $long . “\n”;
    //echo $alt . “\n”;
    //echo $name . “\n”;

    // Insert them into the DB with an SQL statement
    $sql = ‘INSERT INTO `tblMYTABLENAME` (`date`, `lat`, `long`, `alt`, `name`) VALUES (CURRENT_TIMESTAMP,’ . $lat . ‘,’ . $long . ‘,’ . $alt . ‘,\” . $name . ‘\’);’;

    //Your URL will look something like this
    //http://www.MYDOMAIN.com/connecttodb.php?lat=20.1234&long=30.4321&alt=50&name=John

    //Also for debugging to see your SQL statement
    //echo $sql;

    if (!mysql_query($sql,$link))
    {
    die(‘Error: ‘ . mysql_error());
    }
    echo “1 record added”;

    mysql_close($link)

  14. Wagas Sonkar says:

    Hello Toni

    I have exactly the same requirement what your application mentioned here is delivering but when I am trying run it with a simulator its giving error as no source code found. I looked into the trace stack and found it is failing at Thread.Timer main () function (exact name may be different but its the timer).
    I tried to put the .cod file in my blackberry also but there also its showing “Starting transmission…” only event I did put some more prints in the function startScreen(), but it is not going upto them. I did conclude that its the only timer where I am unable to carry on. Please guide me as I am all new for this and reffered so many documents but nowhere find anything like this till now as it seems all ok.

    Thanks
    Wagas

  15. Wagas Sonkar says:

    Hello Toni

    Sorry I forgot to mention that I am using BB 8900

    Thanks
    Wagas

  16. Toni says:

    Hey Wagas – what is the exact error? Does it say “No Source Code Found”? Does it say anything else? I haven’t run into that error before, let me know if there’s any other info.

  17. Wagas Sonkar says:

    Hello Toni

    Thanks for your kind consideration. Yeah its giving me “No Source Code Found” only.
    No other error till time. Could you please guide me with it.

    Thanks
    Wagas

  18. Jane F. says:

    Hi Toni,

    this is AWESOME and inspiring! Just got my curve yesterday. As i’m more from a scripting background, do you mind explaining in a couple of steps how i could get a jar from your above code? Thx!

    jane

    • Toni says:

      Hi Jane -

      I apologize about not seeing this comment sooner, I just upgraded to a new version of WordPress, and suddenly I saw a bunch of comments that I didn’t before, there was obviously some issue with the previous installation. You’ve probably long since figured it out, but just in case -

      If you check out the article on Creating a Blackberry Game, it gives some in depth instructions on how to actually compile the code and load it onto your Blackberry (or run it in a simulator).

      Also, thanks for the kind words – glad it helped!

  19. Fernando says:

    Hi Toni, great example, i have someting similar based on the GPS demo from Blackberry’s site, i use TCP Connection to send the data directly to my server and that works fine, but i have some issues that maybe you can help me, first the battery life its very short when the app is running, its running as a service so doesnt have interface. And second we want to request the position of the BB by sending a command to the device, but the socket doesnt remains open, after sending data the socket comes close and we dont know how to keep the socket open.

    • Toni says:

      Hi Fernando, thanks for the kudos. Not sure about the battery life issue without knowing what’s going on in your code. How often are you retrieving coordinates and how often are you sending to the server? Keep in mind that both those actions drain the battery, so the more you’re doing either, the faster your battery is going to go. Again, I’d probably have to see your code to know why your socket isn’t staying open – but keeping it open would definitely be a bigger drain on your battery, since you’re having to do some TCP keep alive or the like. Depending on how often you need the page itself updated, you could cache a batch of results on the device, and then upload a set of readings at a time less frequently.

  20. Julian says:

    Man, seriously.

    You are a fine programmer.

    I haven’t even tried your code, but the way it is constructed and the kind of help you gave to people is invaluable.

    I’m stumble upon ‘in/reddit ‘in/digg ‘in/lifehacker ‘in/…./n ‘ in you and your awesome site.

    • Toni says:

      Thanks for the kind words, it’s really appreciated! I know a number of other blogs have helped me over the years, so it’s nice to give back too.

  21. yach says:

    Hi Toni
    What would be the result if i try running it on my system,from where does the lat long value will be retrieved from?

  22. Toni says:

    Hi Yach – in the Tools menu in your simulator, there is a “GPS” menu that will tell the simulator what lat/lon values to use. You can both specify static coordinates, as well as a stream of coordinates to simulate movement. I haven’t played with the movement functionality, but I think it can even read in from a file of coordinates.

  23. yach says:

    Toni
    Thanks a lot man..that helped me a lot..

  24. yach says:

    Toni
    Can you help me out in getting started with push api?Searched many online, didn’t come across any perfect example.Can you suggest me other source for materials?

    regards
    Avinash Yachamaneni

  25. harry says:

    hey admin,
    i wanna ask something
    what type of OS can be running with this applicatin?

    please tell me minimum requirements.

    thanks, i need ASAP

  26. Toni says:

    Hi – I’m not quite sure what you mean by type of OS, but as far as what version, I know I developed this originally on 4.7, so anything from that up, which is pretty much the majority of all Blackberrys today.

    Server side, you can run anything you want of course, whatever web server you prefer.

    Avinash – I’m not sure of any good tutorials off hand, but I will keep my eye out later today when I sit down to do some work.

  27. harry says:

    Can you help me make apliaksi GPStracker at HP symbian like Nokia 5800, and periodically sends coordinate data to a server that has been in hosting (via http)?

    please help me
    ^ -*

  28. Jorge says:

    Hi,

    thanks for the fantastic sample, i have a question, how can enable your sample for running all time in the device, the all time the application send the coordinates?

    - I need create a simple app that send to the web application the gps coordinates all time, with app oper or closeed.

    Thanks

  29. Toni says:

    Actually, the app (as-is) would run all the time when put into the background. You would have to define code to tell it not to if you wanted. The only thing to be careful with is how often you make use of the GPS/radio, and how much processing you do, simply because of its effect on battery life.

  30. Sherry says:

    Hi Toni excellent work!
    Dude can u pls tell me the code for that asp page or the php page as I dont have much experience on server side scripting!
    Can u plz tell me how to host those pages on the internet

  31. Hi Tony

    i have developed a tracker in a different way, its logically very similar , get gps coordinates and then send it to a webserver.

    I am working in a Research in Motion partner and i have an issue we have not been able to fix.

    look, the app works fine, but what happend if the user turns off the location services on his bb?

    There is no policy for it on the Blackberry Enterprise Server, turning on location services there is onli in SDK 6 and 7 , do you know any way to turn on GPS on SDK 5? , i have talked to Guillermo Doring, the LA development representant of RIM, and he told me there is no way to do it on SDK 5 , but it is possible in SDK 6 and SDK 7, if you know any way to do so, please tell me

    Regards, and congratulations for your blog

  32. shake says:

    This may not be the most appropriate place to ask but I need to write and app that will do an http get based on my proximity to my home. The short story is I have home automation with a web api and I want my phone to turn my lights on when I get within 1KM of my house.

    Thanks

  33. Toni says:

    Hi Shake – Didn’t see that you wrote this comment a while ago. You’re probably all set by now – but if not: You could modify the above code (or code like it) to accommodate your situation without too much work. It would be something like this:

    1. Use an online mapping programming to get the lat/lon coordinates of your house (e.g. You yourself do this, not programmatically)

    2. In the program, at every poll, instead of uploading the coordinates to a webserver, instead check to see if they’re in the radius of your house. Since you’re dealing with two geographic coordinates, but need the result as a linear distance (to see if its less than your 1KM radius), you’ll need to do a few calculations. There are a few great-circle approximations that will work fine for your purposes. They only take a few lines of trig code. Check out this page for details: http://www.movable-type.co.uk/scripts/latlong.html

    3. Then if you’re within distance, you can then use the http portion of the code above to send a command to your home automation API instead of a webserver. Then just set a flag so it only does it once (and not over and over again).

    Cool idea, good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>