Click here to Skip to main content
15,860,972 members
Articles / Mobile Apps / Windows Mobile

GPS Tracking with Windows Mobile 5.0+

Rate me:
Please Sign up or sign in to vote.
4.60/5 (21 votes)
15 Aug 2007CPOL8 min read 237.4K   5.9K   146   50
Use a Windows Mobile Professional phone with a GPS receiver to create a simple SMS based location tracking program.

Screenshot - Title.png

Introduction

This program is a proof of concept for a larger system that I plan to build. Ultimately, I would like to have a system that allows users to opt in and out of letting their locations be known. The location information would be acquired through an application running on a Windows Mobile 5.0 (or later) device. Such a system has commercial applications (knowing where a delivery or service person is located) and personal applications (e.g.: you are heading to a friend's house and the friend would like to know how far away you are). In this prototype, my goal is to touch on some of the foundational technologies for the system.

For this proof of concept, I wanted to be able to acquire the GPS information from the GPS Intermediate Driver, and wanted a way to have a phone send this information either by request of the phone's owner or one of the owner's contacts. Thus, the fundamental technologies used here are:

  • GPS Intermediate Driver - gets GPS information in a way that won't interfere with other GPS applications.
  • MessageInterceptor - waits for location request and starts the application when one is received.

Required Tools

To run this code, you will need to have Visual Studio 2005 installed, and both the Windows Mobile 5.0 SDK and the Windows Mobile 6 Professional SDK. The 5.0 SDK is needed because I've set this project to target 5.0 devices. The code used for accessing the GPS device is part of the 6.0 SDK (though it runs just fine on 5.0 devices). I've included the compiled assembly for the GPS wrapper with my project, but not the source code. To see the source code for this wrapper, you must have the Windows Mobile Professional 6.0 SDK.

I would also suggest that you have a Windows Mobile 5.0 device to test the application with. You can use the emulators for testing the program. This program makes use of SMS messaging. Depending on your service plan with your phone company, you may have to pay fees for every message sent and received. I fall into this category, as at this point in time, available carriers here in the United States do not allow many phones to have unlimited text message subscriptions on the same phone line as a one that has an unlimited data subscription. Because of this, the emulators may be preferable for initial testing of the program. You can redirect the COM port of the emulated Windows Mobile device to an external GPS receiver connected to your PC, or you can use the "FakeGPS" program available in the Windows Mobile 6.0 SDK to also emulate a GPS receiver.

The Missing GPS Settings Icon

On phones with Windows Mobile 5 Professional and later (the phones with touch sensitive screens), there is an icon in the Settings menu that allows one to set the hardware port over which their GPS receiver communicates. On some rather popular Windows Mobile phones, this icon is missing. It is not erased. Rather, some OEMs saw fit to hide the icon. The icon can be restored by deleting the Registry keys [HKEY_LOCAL_MAHINE\ControlPanel\Settings\GPS Settings\Hide] and [HKEY_LOCAL_MAHINE\ControlPanel\Settings\GPS Settings\Redirect]. If you don't have a registry editor, you can delete these keys by running the GPS Icon Restoration Program attached to this article. Simply copy it to your phone and run it. It will display a message box letting you know that it was successful or that those keys do not exist. You may need to reset your phone after running this program, for the changes to take affect.

How Does this Program Work

When initially run, the owner of the phone is able to enter a pin that will be used to identify location request messages. When an SMS message is received, if it contains the PIN that the user selected, this program will be started up (if it is not already running) and the message will be passed to the program. All other messages will be handled as usual on the phone. When the message is received, the program reads the current GPS coordinates from the phone, and responds back to the sender with a link to a map on local.live.com showing the phone owner's current location.

Catching SMS Messages with the MessageInterceptor Class

As its name suggests, the MessageInterceptor class is used to capture incoming SMS messages and allow your code to act upon receiving the message. Rather than needing to manually check all of the messages yourself, you set up a message rule for the types of messages that you are interested in. Within this program, there is only one property on the class that we have interest in: MessageCondition.

The MessageCondition member is of a class by the same name, MessageCondition. The MessageCondition allows you to specify a string that will be searched for in the message. You can specify that the string must be at the beginning, end, or anywhere within the message, and you can specify whether or not the search is case sensitive. For this program, I've set the MessageCondition class to only search within the body of the message for the presence of your pin anywhere in the message.

C#
_messageInterceptor.MessageCondition = new MessageCondition();
_messageInterceptor.MessageCondition.CaseSensitive = false;
_messageInterceptor.MessageCondition.ComparisonType = 
        MessagePropertyComparisonType.Contains;
_messageInterceptor.MessageCondition.ComparisonValue = this.txtPin.Text;
_messageInterceptor.MessageCondition.Property = MessageProperty.Body;

Once the condition is set, the MessageInterceptor only needs to be enabled, and an event handler must be given to it:

C#
_messageInterceptor.EnableApplicationLauncher(ruleName);
_messageInterceptor.MessageReceived += _messageInterceptorEventHandler;

The user may have exited the program since the MessageInterceptor was created. If a message is received after exiting the program and if the user left the program in an enabled state, then the program will be automatically started. To catch messages that caused the program to start, we must create the MessageInterceptor class in the program's Load event. During load, the program checks to see if the application had registered to be automatically loaded up receiving a message. If that is the case, then the program creates a new MessageInterceptor and gives it an event handler. The application will then receive notification of that message through the event handler.

C#
if (MessageInterceptor.IsApplicationLauncherEnabled(ruleName))
{
    _messageInterceptor = new MessageInterceptor(ruleName);
    _messageInterceptor.MessageReceived += 
      new MessageInterceptorEventHandler(_messageInterceptor_MessageReceived);
    txtPin.Text = _messageInterceptor.MessageCondition.ComparisonValue;
    this.chkFindMeEnabled.Checked = true;
}
else
{
    this.chkFindMeEnabled.Checked = false;
}

Obtaining the Current Location

The Intermediate GPS Driver handles the details of interfacing to the GPS hardware for us. I'm using a wrapper included in the Windows Mobile 6 SDK that simplifies the use of the driver. The code works well, and is easy to use, so I would encourage you to consider using it instead of creating your own GPS reading code. Initializing the GPS object can be done in a few lines of code:

C#
gps = new Gps();            
gps.LocationChanged += 
  new LocationChangedEventHandler(gps_LocationChanged);
gps.Open();

The EventArgs received from the LocationChanged event contains more details than you'll probably ever need from the GPS receiver. I simply save the Position member from the EventArgs and update the _currentLocation object.

C#
void gps_LocationChanged(object sender, LocationChangedEventArgs args)
{
    if (args.Position.LatitudeValid && args.Position.LongitudeValid)
    {
        currentPosition = args.Position;
        UpdatePosition();
    }
}

When the program no longer needs to use the GPS Receiver, a call to Gps.Close() is made to end the object's worker thread. Not doing this could cause the program to never terminate.

Sending a Message

Sending messages is straightforward. In the case of SMS messages, a new SMSMessage object is created with the receiver's number and the message text as its constructor arguments. Then, the object's Send() method is called to deliver the message. Since an SMS message cannot be more than 160 characters, the link sent in the SMS message only contains a user's coordinates and a pushpin.

It would not be practical to receive the SMS message containing the map link on a phone, so you may wonder why the program has this ability. You must remember that computers can also send SMS messages either through another application such as Live Messenger or through built-in hardware such as a GMS modem or CDMA modem.

C#
public void SmsSendCoordinates(string to,GpsPosition pos)
{
    string message = String.Format(responseTemplate, 
                     pos.Latitude, pos.Longitude);
    SmsMessage sms = new SmsMessage(to, message);
    sms.Send();
    this.eventLog.Add(DateTime.Now, to, pos);
}

Sending e-mail messages is just as simple. Create a new email object, populate a subject and body, add an address to the "To" collection, and then call its Send() method. The Send() method for e-mail requires an argument that was not needed for SMS. That argument is the name of the mail account to use. On my phone, the available accounts are named "ActiveSync" and "MMS". Naturally, I would rather not use MMS since my phone service provider charges what I feel to be high tariffs for sending a message via MMS.

Since the 160 character limit is not applied against e-mails I am at liberty to place more information in the link. So when sending an e-mail the program may (Depending on the user's selected options) include custom text and an image for representing the user.

C#
public void EmailSendCoordinates(string emailAddress, GpsPosition pos)
{
    string avatarUrl = string.Empty;
    string displayName = string.Empty;
    string customMessage=string.Empty;

    if(((_Settings.OptionFlags&OptionChangedFlags.Avatar)==
         OptionChangedFlags.Avatar)&& (_Settings.Avatar.Length>0)
     )
        avatarUrl=_Settings.Avatar;
    displayName = optionsUI.DisplayName;
    customMessage = optionsUI.CustomMessage;

    string message = String.Format(detailedResponseTemplate, 
                     pos.Latitude, pos.Longitude, 
                     Utility.UrlEncode(avatarUrl), Utility.UrlEncode
                     (displayName), Utility.UrlEncode(customMessage));
    EmailAccount account = 
      (new OutlookSession()).EmailAccounts[_Settings.EmailAccount];
    EmailMessage msg = new EmailMessage();
    msg.To.Add(new Recipient(emailAddress));
    msg.Subject = "My location";
    msg.BodyText = message;
    msg.Send(account);
    this.eventLog.Add(DateTime.Now, emailAddress, pos);
}

What's Next

There are quite a number of features I would like to add to this program. In the next revision, I plan to add a mapping control so that users can see each other's location from their phones. I may also add support for Windows Mobile 5 Standard Edition (the devices with no touch screens). To accomplish this, there needs to exist a web server. Once those two pieces are working, I plan to use the Windows Live Search and MapPoint APIs to provide functionality for finding points of interest and getting directions to them so that users can meet each other.

History

  • 15 August 2007 - Article published.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I attended Southern Polytechnic State University and earned a Bachelors of Science in Computer Science and later returned to earn a Masters of Science in Software Engineering. I've largely developed solutions that are based on a mix of Microsoft technologies with open source technologies mixed in. I've got an interest in astronomy and you'll see that interest overflow into some of my code project articles from time to time.



Twitter:@j2inet

Instagram: j2inet


Comments and Discussions

 
GeneralJoel, do you consult or need some extra paid work? [modified] Pin
Navdog9-Oct-07 2:22
Navdog9-Oct-07 2:22 
GeneralSimilar program Pin
Joel Ivory Johnson29-Sep-07 3:12
professionalJoel Ivory Johnson29-Sep-07 3:12 
GeneralUnlimited Data + SMS Pin
Teksupptom26-Aug-07 20:18
Teksupptom26-Aug-07 20:18 
GeneralRe: Unlimited Data + SMS Pin
Joel Ivory Johnson27-Aug-07 3:08
professionalJoel Ivory Johnson27-Aug-07 3:08 
GeneralRe: Unlimited Data + SMS Pin
Teksupptom27-Aug-07 3:34
Teksupptom27-Aug-07 3:34 
GeneralRe: Unlimited Data + SMS Pin
Joel Ivory Johnson27-Aug-07 4:41
professionalJoel Ivory Johnson27-Aug-07 4:41 
Generala couple of questions Pin
ThetaClear18-Aug-07 1:24
ThetaClear18-Aug-07 1:24 
GeneralRe: a couple of questions Pin
Joel Ivory Johnson18-Aug-07 8:07
professionalJoel Ivory Johnson18-Aug-07 8:07 
1) - Up until now all GPS receivers that I have seen for Windows Mobile devices have worked identically; they communicate using over a COM port (either a physical com port or a logical one over bluetooth) and they have all used NMEA. No special software is needed to interact with them. If you know what COM port the GPS hardware is using you simply open the port using the SerialPort object and continually call ReadLine() to get the sentences. The sentences are easily parsed using regular expressions to get the information of interest. The disadvantage of interacting with the GPS hardware directly is that only one program can do this exclusively. If later you have other applications running that would like to use GPS information they will not be able to connect to the port.

2) - If you are reading directly from the COM port associated with the GPS hardware then the SDK has no influence at all on the format in which you receive the information. The information is being passed straight to you without any type of filtering or modification. More information on the format itself is readily available. Take a look at http://aprs.gids.nl/nmea/[^] for the spec of the sentences. When I was creating a GPS app for Windows PocketPC 2003 the only way to interact with the GPS hardware was through the COM port. I was only interested with a single piece of information from a single sentence so I just made a single regular expression to catch that sentence (see this article[^]).

3) - Nope, as far as I know no one has ported the .Net Framework to the Symbian Operating System. I believe you will need to use C++. I can't say that I am familiar with Symbian development, but you may want to look at this code example[^] as it may have what you need.

Joel Ivory Johnson

Computer Science, spsu.edu

GeneralRe: a couple of questions Pin
ThetaClear18-Aug-07 21:37
ThetaClear18-Aug-07 21:37 
GeneralRe: a couple of questions Pin
Joel Ivory Johnson18-Aug-07 23:53
professionalJoel Ivory Johnson18-Aug-07 23:53 
GeneralRe: a couple of questions Pin
ThetaClear19-Aug-07 2:33
ThetaClear19-Aug-07 2:33 
Generalarticle format - too wide Pin
Abu Mami16-Aug-07 0:46
Abu Mami16-Aug-07 0:46 
GeneralRe: article format - too wide Pin
Joel Ivory Johnson16-Aug-07 1:50
professionalJoel Ivory Johnson16-Aug-07 1:50 
GeneralRe: article format - too wide Pin
Abu Mami16-Aug-07 2:12
Abu Mami16-Aug-07 2:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.