Some time ago, I stated in another article that I'd take the idea of location broadcasting and develop a mobile solution as a follow-up. The problem back then was I had no means to get location data off of a cell phone, or a way to make it useful. My, how times have changed since then! In this article, I'll demonstrate how to get your phone's GPS coordinates…

Phone technology is maturing at an alarming rate. A large number of current generation phones have GPS built in. Nonetheless, “smart” phones have an average price tag in the hundreds, and most of us haven't rushed out to buy a replacement for our current phone (especially with the troubled economy as of this writing).

The fact that GPS isn't (yet) ubiquitous is the real difficulty in location-aware development. The goal here is to get the location from any phone, not just GPS-capable phones. Therein lies the difficulty.

If you haven't already played with Google’s Mobile Maps, I highly recommend it. It’s really a handy little app, especially when you're on the go and need a map (happens all the time for me). But, Mobile Maps works on my phone, and I don't have GPS. How is that possible? Google has figured out how to determine your location without GPS, with their Mobile Maps, using common cell phone data. That means finding location is possible without GPS. In fact, let’s start our project by deconstructing how Google’s Mobile Maps works, and build it back up in C#.

I won't go into details in this article about protocol or packet analyzers (I'm using Microsoft Network Monitor). Suffice it to say that the first step to deconstructing Google Mobile Maps is to analyze HTTP requests while Mobile Maps is running through ActiveSync.

A quick peek under the Mobile Map hood reveals a couple things. First, Google is posting requests to http://www.google.com/glm/mmap for location data. I've scoured their APIs, and this isn't something that appears to be documented. That means, we're on our own for figuring out how to package and send data. Secondly, it’s clear that they're sending four key pieces of data:

Cell Tower ID

Location Area Code (LAC)

Mobile Network Code (MNC)

Mobile Country Code (MCC)

That’s great news! As it turns out, almost all cell phones have this data readily available. Windows Mobile (5 and 6) has a native API to get those four pieces of data called the Radio Interface Layer.

We need to crack open the Windows Mobile Radio Interface Layer to get cell tower data. No worries, it’s not as complex as you might think. Plus, you can search for RIL on MSDN for details on the entire RIL library. It’s very well documented.

We're only interested in the cell tower portion of the RIL. The first thing we need to do is add the necessary PInvoke DLL Import signatures to call into the Radio Interface Layer.

These four methods contained in ril.dll are our gateway to cell tower data. With these methods, and their backing RILRESULTCALLBACK and RILNOTIFYCALLBACK structures, we can easily call Windows for our cell tower data.

That was easy, thanks to MSDN! Now, we can call GetCellTowerInfo(), and we'll get a strongly typed CellTower class with all the tower details in return. I always prefer to work in a strongly typed representation of PInvoke output instead of marshaling pointers.

*Note: this code will not work in an emulator unless you have the Cellular Emulator configured and running as well. I suggest using your phone instead of the emulator.

Great, we have cell tower data, but now what? We still don't have GPS coordinates. We know that Google is making this translation happen, cell data to lat & long, so let’s continue to dissect Google Mobile Maps. Another look under their hood shows that they're posting binary data to the URL above. Again, analyzing protocols is outside the scope of this article. What you'll find is that we need to post our data in a 55 byte array. Most of the bytes are empty (0), but we do need to fill in a few key items in the array. Here’s the code to create and populate the byte array with our cell tower data:

In short, we can pass in our four parameters: Tower ID, LAC, MNC, and MCC, and we get back a byte array we can post to Google via HTTP. The code below demonstrates the whole HTTP request, which takes our strongly typed cell tower data (from the PInvoke above) and returns the latitude and longitude from Google’s database!

Let me take a moment to describe what just happened. We read our phone’s cell tower data from the OS, sent it off to Google via HTTP, and got back the latitude and longitude. How is that even possible?

The FCC keeps record of each cell tower in the US. Google isn't doing anything (too) magical. They're simply looking up the details for the tower we're submitting, and returning the tower’s well known location in lat/long format.

Google is not the only database of tower locations, however. OpenCellID.org is an open source initiative to map all cell towers and their GPS coordinates. Yahoo! is doing the same thing with their ZoneTag service.

Why go through all the trouble to use Google if there are easier alternatives?

That’s a great question! Simply put, Google is the most comprehensive database. OpenCellID and ZoneTag are newer, and their databases aren't complete. I can't even get a valid GPS result here at home, a suburban area in a major city, with either of these “beta” services… but, Google works everywhere I've tested so far.

Naturally, cell tower data isn't as geo-precise as GPS. You can't tell from your cell tower data if you are 10 feet or 1000 feet from the tower. In other words, it’s almost always preferable to use GPS when it’s available, because of its precision. There are exceptions like when you're indoors and can't get a GPS signal; you'll likely still have a cell tower connection.

Getting GPS data from a compatible phone is even easier than getting cell tower data. Even better – Microsoft has distributed a library to do all the heavy lifting. All we have to do is subscribe to the event that’s fired when the Microsoft GPS class detects a location change. Microsoft has done the rest.

The Holy Grail?

So far, we've built two mechanisms to get your phone’s latitude and longitude. We have as much potential now as, say, Google Maps! It would seem like that’s a great place to do a victory dance, submit the code, and have a glass of eggnog (it’s 5 days until Christmas while I'm writing).

But, what good is location anyway?

I generally know where I am, so knowing my location doesn't help much. Applications like Google Mobile Maps already show me my location, but they don't do anything else with it. I just don't think the article can end here… not yet.

It’s my opinion that the real value of location based services is in sharing your location, not just knowing your location. This is the next inevitable step in social networking.

I'm a firm believer in the creative process, and there are lots of developers who are more creative than me. I'm going to shift direction a bit and try and provide creative influence rather than a concrete solution. Why don't you let the rest of this article be your mobile location muse? You should come up with the next great idea on what to do with your location.

My first creativity catalyst is updating your Yahoo! Fire Eagle account with your latitude and longitude. Fire Eagle is a new service from Yahoo! that takes in your location and “broadcasts” it to the applications you've subscribed to (in their rapidly growing gallery).

Actually, that’s the reason this project was named DeepCast. We're broadcasting our location to a (potentially) deep list of services and providers. Not just a broadcast… a deep cast =).

Fire Eagle uses Oauth as its authorization platform. I'm really not all that familiar with all the details of Oauth. What I do know is that there’s a manual process for authorization before any application can make updates.

The first step in Oauth authentication is to generate a request token and secret pair.

Then, you can browse (via your desktop browser) to the authorization URL.

You have to manually confirm that the application can update your profile.

Finally, you have to exchange your request token and secret for an authorization token and secret. These are the values you need to save and use every time the application attempts to update your location.

Now that you have an authorization token and secret pair, you can update Fire Eagle as often as you like. Fire Eagle will then broadcast your new location to the underlying applications you've subscribed to.

I've never been the biggest fan of Twitter. It just takes too much work to get too little useful information (just my opinion…). But, what if Twitter could show me where people are?!

What if we could post a tweet with a link to a Google map showing your location? That seems to have some utility.

There’s very little to describe in terms of updating Twitter. It’s as simple as making an HTTP request. The one difficulty is adding a hyperlink to the message. Twitter uses a form of URL encoding that truncates most query strings. We'll generate a TinyUrl to get around that issue.

Note that there’s a location convention, ‘L: lat, lon’, that’s got a deeper purpose. That format can be parsed by the folks at TwitterMap.com. Again, we're trying to make location useful to as deep an audience as possible.

Naturally, sharing your location isn't the only way to make the information useful. The project has been structured in a way that location can be used internally as well as externally. The main page, for example, makes use of the same location that the external-facing services use. The map on the main page is simply a browser control, with the URL being set to a Yahoo! Maps image. Nice and simple, which is what I wanted!

That’s right – it’s your turn. Most of the project has been stubbed out for you to add your own location-aware service. If you've read this far in the article, you're probably interested in location services, so feel free to modify the project and code away! I'm encouraging all readers to use this project as a stepping stone to the next big idea. Some of the possible uses for location I can think of are:

Track where you go via a web service. Create a backing website that shows a map of your tracks - when and where you were. Draw a history of where you've traveled.

Hi,I am using a GSM Module and a MCU with a sim card, i have the MCC , MNC and LAC and CI, and after analyzing the C# code in the article ,i constructed this message 000E00000000000000000000000000001B000000030C12255A000000000000090D1BB12854799D000000030C12255AFFFFFFFF0000000000FFFF0000000000and then I made the following POST request:

First of all , Thanks so much for this article , It is really genius. Thanks.

Dear Experts,

Did anyone succeeded to make it working on J2ME.

The other thing does the connection to google to get the location cost , ie do I need to subscribe into GPRS service or it is free .

Another question , the accuracy when I use google maps is almost 5-20 meters. But , when I use the CellID , it is almost the same even If I moved with the mobile for 200 meter . So , how google knows the exact location of mine.

These Mobile application examples need to further distinguish their code as being for Windows Mobile 6 Professional OR Windows Mobile 6 Standard. Windows now has divided Smartphones into Touch-screen phones, which use the Windows Mobile 6 Professional OS and Non-Touchscreen phones, which use the Windows Mobile 6 Standard OS. There are seperate SDK's for each of these OS's. If your Smartphone is a Non-Touchscreen device, it cannot use the Professional SDK and must use the Standard SDK and vice-versa. Thanks again to Microsoft for confusing the hell out of us lowly developers.

If you want to run the DeepCast sample code on your phone as-is, you must have a Smartphone running the Windows Mobile 6 Professional (touchscreen) OS. However, if you do not have the touchscreen but do have Windows Mobile 6 Standard, you can still use this code with modifications. First, you will have to recreate the entire project as a Windows Mobile 6 Standard Application and then port the source code files over from there.

hi, I am trying ur developed code on HTC Touch WinMo6 PocketPC. Problem i am facing is that response that i am receiving. response data length is 7 only, hence i am not able to retreive the long and lat. is it that the request uri may have changed or the request packet.

I tried to do the same in J2ME, i hardcoded the 4 parameters just to get it to work. But it seems that what i get back are not the right Lon and Lat values. I guess it's the getCode() method that doesnt work exactly the same way. And the only thing i can think of is that double in java and c# are treated differently. Any one have any ideas?