Introduction

Location-based services (LBS) are becoming more and more popular nowadays. There are several mobile applications that detect user's current geographical location, provide related information about the location and also display location in Web. This article discusses how to develop a similar application (both mobile and web part) that will allow the user to save their location from mobile and display their current location in web pages with location history browsing in map. I will show a live demonstration where all these are working together!

Technologies Used

Although I will be using J2ME Wireless Toolkit 2.5.2, PHP, HTML, CSS, jQuery, MySQL (a little bit of everything :P) in this article, strong technical background on these is not required. You can use any combination of technologies to develop a similar application.

A Quick Tour

Let's have a quick view on what we will be developing throughout this article. Following are the screenshots of the Mobile application:

Now when user hits "Locate Me" menu, we just need to call getLocation() method and print the array on display. It's as simple as that. Now, we want to display the location in a map. I am using MidMaps: Google Maps Java ME library. When user hits "Map me" menu, we will set MapViewer class as our current display and pass location data to it so that it can render the map.

At this point, we have the necessary methods to detect location and display them. Job half done! Next is just to save them in database. Let's finish those asap. First let's create a table in database (MySQL):

We also need to write a few lines of server side code to handle this request and save data in the database. I will be using PHP for this purpose. Here it is...

Now, we have almost completed one full cycle. That is detecting and saving location in server. However, we are still missing one thing. In the above approach, user needs to click every time in menu to save location, what if we could write a service that will continuously save location (e.g. save location after every five minutes)? That's also possible and in fact very easy to implement with Location API. We need to implement LocationListener interface and thus code two methods locationUpdated() and providerStateChanged. We will add two commands "Start" and "End" to fulfill this purpose. Whenever location is updated, locationUpdated() method is called where we save the latest location in database. So, think you are traveling and turn this service on, the whole path is saved in database and then in web application you can create cool animations that will traverse the path according to the increasing/decreasing order of time! Well, we are not so far from that. Let's now finish implementing this interface:

Each time a location record is saved, we update a count variable and print it. So, while running this service, we can have a hint about how many times it has stored record. Now all we need is to register our MapMe MIDlet to LocationListener. So we write:

Yes, it's as simple as that. But there is still one issue, our MapMe class implements CommandListener as well and thus handles Command (i.e. "Map Me" click events). So, when we hit "Start" menu, commandaction event thread handles this and as long as this thread is not finished, no other button events can not be fired. But as soon as user hits "Start", a pop up dialog box will appear asking for permission to use GPS data. But user will not be able to click it because the commandaction is not finished yet. A deadlock!! Yes, it is so. So, what we actually have to do is to start and stop listener in different threads:

Auto Updating Current Location

If you browse my website, at the right side of my homepage, you will find a map that shows my exact current location. And if I save a location while you are at my homepage, only the map will refresh (as it is implemented in Ajax) and you will experience a sudden move in the map. Isn't that cool? Yes, and it is very easy to implement! All we need is to write some code that will repeatedly look for updated data in the server and as soon as it detects a new record, i.e., if current latitude and longitude do not matches with the previous one, a change has occurred and it will update the map. Let's first write getCurrentLocation() method at the server side:

I have picked the top row (and also the most recent row) from current location table and returned it encoding in json. In the web site, a JavaScript timer will handle it to load the map and keep querying it in a regular interval to detect change. I will write these few lines of JavaScript using jQuery library. Here it is:

Location History Browser

Here mapDiv is the div where I am loading the map. So, now if you set this up in your homepage, whenever someone comes to that page, he/she will see your exact location and also get notification of Location change. Ok, we are almost at the end of this article. One more interesting thing I will show is the Location History Browser. Our current_location table consists of all the GPS traces saved in order of time. So, we can easily get the traces for any specific date! The idea is to allow a user to see the traces of any specific date and develop some navigation tools to play with them. First, let's finish a method getLocationByDate($date) which will return json payload of GPS traces for a specific date:

Now we can just call getLocationByDate($date) with a date and populate the data in map. So, the history browser is done! Wait; there are still some things we are missing. Say I have 50 GPS traces saved for one day and does that actually make any sense to display 50 points in the map? Will it add any value to the user? For a user, these are just random points and how he/she will get idea where I visited on that day? Say, I was at place 'A' at 7 am and at place 'B' at 9 am. These will appear as two points, but no time is attached. Here is what I am going to do to make these really usable to the user:

Every point in the map will be clickable, means if you click a point in the map, the map will pan to that position, i.e., treating that point as a center point and a small box just below the point will show the time! (Remember, the recorded_datetime field in current_location table)

We will add 5 navigation buttons (actually we are going to develop a GPS trace player!). They are:

First trace: Move the map to the first recorded trace of that day.

Previous trace: Move the map to the previous trace from currently selected trace thus enabling user to traverse the map in decreasing order of time.

Play/Pause: Yes, Play! Play the GPS traces. This will start playing the traces from currently selected trace. Means, the map will move automatically to the next point in order of time and keep moving until user hits Pause. To make the transition smooth, I have added some delay before every move. Trust me, you will like the animation.

Next trace: Move the map to the next trace from currently selected trace thus enabling user to traverse the map in increasing order of time.

You can try it out at http://www.amitdutta.net/gpsTraces.php. Pick May,14,15 or June 10, 2011 as these days have lots of traces. If the points are too dense, zoom the map and then start playing!

Not Yet Implemented

In the Location History Browser, while user picks a date, the map is filled in the traces of that day. But these traces seem clustered into one place due to the default zoom level. An algorithm should be implemented in the server side to determine the zoom level dynamically based on GPS traces.

There is no option in "MobileMap" to specify server URL (i.e. where to save data. This is hard-coded and every time I want to change server URL, I need to modify sources, build and re-deploy. I need to implement some way to change default server URL.

Using the Code

There are three simple steps to make the whole system work properly. Here they are:

Setup Server-Side code and database: For this part, you will need a http server that can run PHP code and a MySQL server to save location traces (I will not discuss how to integrate PHP and MySQL here). For ease of understanding, I assume your HTTP server's URL is "http://www.test.com".

Go to "ServerSide-setup-for-MobileApp" folder. Run "current_location.sql" script to your database (here MySQL) to create tables for the application. Open "config.inc.php" file and provide the necessary information (username, password, hostname) of your database setup.

Copy LocationSaver.php and config.inc.php to a folder under your http server. Suppose you have copied these files to a folder named "Mobile". So now, "http://www.test.com/Mobile/LocationSaver.php" should be publicly available over the internet, means we can communicate with this from mobile to save GPS traces.

Setup MobileApp:

"MapMe" is a Netbeans project. So, it will be easy to open it with Netbeans. It's also possible to compile it with j2ME wireless toolkit's control panel.

I have used j2me wireless toolkit 2.5.2 because it has Location API support. Older version may not have this support.

If Netbeans shows reference problem. Right click on the project and bring up the project properties Window. In the "Optional Packages" list at Right-Bottom, check the checkbox "Location Based API".

In "MapMe.java" line 21, change the "URL" field according to your setup (for example, here the value of "URL" field will be: "http://www.test.com/Mobile/LocationSaver.php?").

Now, copy all the files under "Codes\WebApp" to directory where you want to deploy. Say, you have copied these files to "http//www.test/com/WebApp". Now, "http//www.test/com/WebApp/AutoUpdate.html" will display your most recent location and "http//www.test/com/WebApp/LocationHistory.html" will allow user to browse your GPS traces!

Installation

Build the attached "MapMe" project (inside "Codes\MobileApp" directory) and copy "MapMe.jad" and "MapMe.jar" file to your mobile device and install them. For best GPS results, turn on all the GPS positioning methods. In my Nokia N95 8GB, I navigate to "Menu/Tools/Settings/General/Positioning/Positioning methods" and turn on "Assisted GPS", "Integrated GPS" and "Network Based GPS".

For Non GPS Mobile Devices

If your mobile device does not have a built-in GPS, you still can develop a similar application. You need to use CellId (A CellID is a number which is associated with a specific cell (the radio tower to which your handset is connected)) and use open source database of CellIDs (such as OpenCellID). I would recommend you read this article and this one for non GPS based phones.

What Now?

If you have come here, that means you have gone through this long article (I hope you have not just scrolled down here :P). I would like to hear your thoughts about this implementation. Share your ideas, vote if you have liked it and leave a comment...