Introduction

Most of the new Windows Mobile devices include a GPS receiver as part of the standard configuration. However, one problem is that of the repeated "cold start." Presumably to save battery life, the GPS receiver is turned off when it is not being used. Unlike standard GPS devices, mobile GPS chipsets do not save data when they are powered off, requiring a "cold start" each time they are used. This means up to 10 minutes of keeping the phone motionless until it has locked on to the satellites. Windows Mobile 5 and 6 standard / smartphone editions do not provide user-accessible configuration options to change this.

However, if the GPS remains turned on, even after losing its fix (i.e. by going inside) it will be able to re-acquire its location within seconds of being placed in an area that has a signal. Also, once locked on to a signal, the receiver is able to hang onto it even when going into areas where it would not be able to lock on to the signal from a cold start.

I originally dealt with this annoyance by leaving Google Maps running all the time in the background. This solution was imperfect, since it used a lot of memory and CPU, as well as downloading data from the Internet to update the map, which is quite expensive on many mobile devices. I instead designed this utility to run in the background, keep the GPS open, and poll its status at a user-defined interval.

This program is also useful if you want to quickly test your GPS to make sure it is configured correctly and/or has a signal.

Background

How to Use the Microsoft Intermediate GPS Driver

The library used in this app is an open source sample provided for free with the Windows Mobile 6 standard SDK. It encapsulates the API hooks, allowing for quick and easy access to the phone's GPS using C# managed code.

I have included the necessary source for the library; if you have the Windows Mobile 6 Standard SDK, those files can also be found at "\program files\Windows Mobile 6 SDK\Samples\Smartphone\CS\GPS".

Add the whole folder to your project (minus the demo app), and add...

using Microsoft.WindowsMobile.Samples.Location;

... (or the VB equivalent) to your classes that require GPS access.

IMPORTANT: Known Issues with the Microsoft .NET Compact GPS Library

One of the reasons that unnecessarily complex solutions have been posted here and elsewhere is, THE WINDOWS MOBILE 6 SDK LIBRARY DOES NOT WORK PROPERLY IN THE WINDOWS MOBILE 6 EMULATOR. HOWEVER, IT WORKS PERFECTLY ON AN ACTUAL PHONE. A bunch of NMEA files are included with the SDK to simulate navigation on the emulator... when used with the "FakeGPS" driver (for testing GPS apps in the emulator) the latitude and longitude are alternately invalid or ridiculous (near the South Pole.) There is an MSDN blog somewhere apologizing for this goof and giving a possible fix (an equation to convert decimal degrees to standard latitude-longitude, which does absolutely nothing to solve the problem.)

That said, use the library. It makes getting GPS data easier than opening a text file, as you will see in the code below. The problem is with the emulator. My advice would be, in the emulator, test with simulated latitude and longitude fed in however you see fit (i.e. an array of values, text file, etc.), then wire your position-getter methods up to the library and deploy to an actual GPS-enabled device. It will function as expected.

The project that accompanies this article, while small and simple, demonstrates the use of the core methods that you will actually use when building GPS-enabled applications:

Start the GPS:

Gps g = new Gps(); Gps.Open();

Determine if the GPS is ready and knows its location:

if (g.GetPosition().LatitudeValid)
{ //Has position: do something with the data }

Accessing the GPS location data is almost too easy. Here is the UpdateStatus() method that is the heart of the program that checks if the GPS is locked to a sufficient number of satellites, and then gets its latitude and longitude.

How to Test in the Emulator

Seeing as the "FakeGPS" emulation does not work, on-device testing should be started early for any application built using these libraries. Building the application here that I have posted for download results in an EXE and a DLL. Place both in the same folder on your mobile device, and you should be good to go.

Unfortunately most devices are shipped without the newer versions of the .NET Compact Framework. If you have the Windows Mobile SDK, there will be a CAB for each different processor. Don't worry about breaking your phone by choosing the wrong one - it will simply refuse to install. You can also download the framework by itself from Microsoft.

Deploying to the Device

The project is currently set to use a Windows Mobile 6 standard build target (smartphones such as the Motorola Q9H or Samsung Jack II. It will also build for Windows Mobile 6 professional (touchscreen PDAs / PocketPCs.)

It has been tested in the real world on a Motorola Q9H with standard configuration but should work on any of the above mentioned device categories provided that a GPS chipset is present and configured properly.

Windows Mobile 5 devices should also accept this, and other applications using the intermediate GPS driver. Switch the build target in Visual Studio, and look for warnings on compile: if you are using components (mainly UI ones) not allowed on 5 (i.e. an embedded web browser control that can be manipulated by the host application) you will be notified at build time, and can make the appropriate (minor) changes.

Obviously, to make a production GPS application using .NET CF, you will want to create a Setup and Deployment project and explicitly specify that the .NET Compact Framework 2.0 or 3.5 be included with it, rather than making the user download it separately. The current build configuration is for 3.5, but it builds perfectly to a 2.0 target as well without modifications.

Share

About the Author

Sam Rahimi currently leads the web team at World Golf Tour (www.wgt.com) and has an extensive background in ASP.NET, specializing in social networking and casual gaming.

Previously, he has worked for Roblox Corporation on their unique children's MMO as well as spending two years as team lead at Supernova.com, helping bring their social networking site into the modern era and doubling traffic along the way.

Sam started as a classic ASP engineer as a summer job 6 years ago to make some money to pay for tuition - to finish a degree in political science - and needless to say, never looked back. His experience has lead him to gain additional experience in the mobile space - J2ME, Android app developmentm, and SMS protocols.

And sure, the other engineers in SF may have an IPhone - Rahimi sticks with the EVO all the way!

Your application looks great but have not been able to use it, so I would appreciate your help a lot!

First of all I'm not an expert on .Net but I feel good myself with VB6, I have VS2005 on my computer and could not open the cs project because according what I read it was created on VS2008.

What I did is :

1. create an empty C# Mobile app and copy all the .cs files into. I used the name as GPSController and noticed later it was KeepAlive, hope this does not matter as I changed in From1.cs name to "GPSController"

2. Built the application and receive an error on "using System.Linq;" I google it and found on some forums that I need to add System.Core.dll, but did not find it.. so I do not know how can I add a reference to fix it, so the first idea... maybe dumb but I commented that line, and it worked. So Now I have an exe file, but do not have the dll that suppose is required.

3. I copied the file into my mobile HTC TITL, when I run the application it shows me the main screen but if I click "Turn On" to the GPS, I receive the next message: "Error: Could not find GPSdevideSystem.NullReferenceException at GPSController.Form1.mnuTurnOn_Click()"

I will send my created files on an email to you, and will send same info to your email.

Thanks for a great article. I had an idea for a small project by way of introducing myself to windows mobile. I was impressed by a friend's small GPS data logging device and having just upgraded to a smartphone I thought it should be fairly (ahem) straightforward to use the phone's GPS to achieve something similar.

I imagine it would be simple to update the code to store each fix as they come in. My question is this: how frequent could this application reasonably acquire this data and would reducing the polling frequency impare the battery life any more than already discussed?

I did something similar, involving taking co-ordinates at regular intervals and posting them to a web server...

Your bottleneck is not going to be with acquiring the data - I found that 1 second intervals were totally reasonable on a midrange device (although the shorter the interval, the more battery you use.)

If you're logging to a file on the device itself, then you should have no worries - where it gets tricky is if you're performing network operations which tend to be unreliable on mobile devices - and to ensure good thread management in this case - I would recommend a polling interval of no less than 30 seconds if you're going to be sending the data over a network as it is acquired.

I can NOT seem to be able to get any GPS data. The code works fine, the GPS is enabled, but the numbers, when I show the Lat & Long numbers, they're always Zero. My GPS IS enabled in my phone, and I'm performing these tests outside, there's really nothing around to interfere. I simply cannot seem to actually retrieve any data? If anybody has any suggestions, I would be ETERNALLY grateful!

I have downloaded the WM6 SDK.
I am getting "The project could not be opened because it refers to a device platform that does not exist in your datastore."
I don't know whether it is relevant or not but I built a blank project targetting Windows Mobile 6 Standard and compared the .csproj files. The PlatformID is the same but the OSVersion is different yours is 5.2 the empty project I created is 5.02.

Hmm... Probably a versioning issue with the SDK. Plus I am still using the VS 2008 CTP - also may be an issue.

I would recommend creating a new project targeting your desired platform and then just import the files from my project using the existing folder structure. Since there are no external references it should work fine that way.

Do you have visual studio? If so, just build the project... It will produce two files, an EXE and a DLL. Then copy them into a folder on your phone or PDA using ActiveSync.

If you don't have visual studio I can build it for you and send you as a prepackaged installer. Just email me, samr@supernova.com

Let me know how it goes...

p.s. The interface is a little buggy in the version I've posted right now - some of the labels are covered up by the instructions text (which you can just get rid of completely - there is no code attached to it.) I'll be posting an optimized version this week along with a sample of sending latitude and longitude to a web server whenever the GPS is polled.

If anyone installs this, let me know if it worked or did not, and what device you are using... again, this has only been device tested on a Motorola Q9H, and mobile devices tend to have their quirks (though much less with .NET CF than with Java!)

Hard to say... the Q9H that I am testing on has extremely poor battery life to begin with, seeing as I walk around with it listening to streaming radio (over the 3G cell network, not WiFi) which itself drains the battery from a full charge in about 2 hours.

I can't imagine the impact would be that bad, seeing as the GPS chipset only listens and does not transmit any data or poll any server. And decoding NMEA messages is not particularly CPU intensive - just a text-parsing job, basically...

But there definitely needs to be a controlled test of this. I unfortunately do not have time to conduct such tests at the moment, but if anyone here has a windows mobile device with GPS and wants to help out by determining this, it would be greatly appreciated!

I'm actually trying to find a good way to test the battery impact of certain types of tasks myself. The problem I run into is that anything I do to check the battery life will potentially impact the battery life; for example, if I were to bring the unit out of a low power state to see what it's battery life were then I have caused the phone to use more power by doing so. And I can't say that I completly trust that the battery sensor built into the unit passes back linear data.

I know exactly what you mean - It reminds me of that Heisenberg Uncertainty Principle I learned way back in my first year of college - that in certain systems, the act of taking a measurement will invariably influence the value returned.

I agree - the battery life indicator is not linear... but it most likely is consistent. What I mean by that is, if it says "20% remaining" one time, it won't actually be 20%, but it will be an unknown constant value - so the next time it says 20%, it should be the same.

So I would propose the following test case:

- Add a HTTP web service call to each loop of the timer... have it send in a time stamp every minute (or whatever interval you choose)... when the requests stop coming, the battery has died (start this with only 10% battery remaining so it doesn't take days!)

- Perform the same procedure with the GPS closed and the line that attempts to poll it commented out.

Assuming you properly control for other variables (i.e. running processes, incoming calls, etc.) this should work pretty well.

The radio part of the GPS uses next to no power, the DSP part burns it up so fast it will freak you out.
I've written software that uses the GPS in four different smart phones, and can honestly say that the on board GPS will reduct your standby battery life from ~120 hours to 2.

The best indication of how much power these little beasts use it to run the app, and just hold the phone. If you feel it getting warm after about 5 minutes then you'll know your batter life is going to take a nose dive.

If the GPS in your device supports AGPS, then you will probably get a lock in 30s and don't need to leave it running to get quick access to your location.

Fido and Rogers in Canada don't seem to offer AGPS (yet they still try to sell you a $10 / month "telenav" subscription that gives you a product strikingly similar to Google maps just using the regular GPS.)

I'll try the holding the phone thing, let you know what happens... however the battery did seem to behave normally yesterday (I left the keep-alive on all day) and only took a nose-dive once I started watching streaming FLVs with a dodgy software decoder

If indeed the DSP is as inefficient as you say, that is just bad, bad design - those little handheld GPS units that you take if you're scared of getting lost in the woods last for a lot longer than 2 hours! Then again, sometimes I think the designers of Windows Mobile forgot they were building for a phone and not a miniature laptop!

If you feel it getting warm after about 5 minutes then you'll know your batter life is going to take a nose dive.

that's one of the best battery life test ever!

I have a question about GPS Intermediate Driver. Lets just say I have Gps.Open() but the App on my mobile does not get any coordinates for a while (assume there are 0 satellites). Does the battery consumes the same amount of energy like when there are satellites available and GPS gets location? Thanks in advance.

In a recent WebCast from MSDN, the presenter talks about how easy it is to unwittingly drain a mobile device's battery very quickly just by sticking to established patterns which work perfectly on desktop systems (with mains power and big heat sinks). He particularly stresses the need to avoid using timers and polling for results.

The GPS is raising events all the time it's on, so that must be a fixed cost (in terms of battery life), as is the actual code processed in doing whatever work you want to do for each execution (update a map, for example), but we must weigh handling approaches...

On one hand the event could just be ignored or dropped until your poll/timer actually looks for a result. There's a cost in terms of battery life for each GPS event, even if nothing catches it, and there's the cost of your timer loop.

On the other hand there's the cost of responding to every GPS event with something to count and decide when to execute the app code, say every 10th event.

I don't propose actually taking such measurements, but just wanted to highlight the fact that we developers have until now been able to disregard the energy and clock ticks our apps use, thanks to 750 watt power supplies, virtually limitless RAM and supercooled GHz quad processors. In the world of mobile devices we're back to measuring processor speed in hundreds of Hertz and having to make sure the device doesn't die between charges.

I have been testing an app that I wrote. Battery was a concern and GPS WILL drain your battery, so I implemented a timer to call Stop(). The problem I am having and can not figure out, is that when I call Stop() from a timer, the app will hang. The problem is not consistent, sometimes it will other times it will not. Even when invoking the button pressed event (which typically always stops without hanging). Any ideas? I have a hunch that it is hanging in the 'hold' block.