Windows Phone GPS Emulator

Windows Phone GPS Emulator

  • Comments 24
  • Likes

All Windows Phone devices have a built-in Assisted GPS (aGPS), which is used by various phone applications including maps, camera, and search (to provide location-based search results). Developers can access location information on Windows Phone by using the System.Device.Location namespace, which is supported in .NET 4 and later. The GeoCoordinateWatcher class supplies location data based on latitude and longitude coordinates.

Working with the GeoCoordinateWatcher is relatively simple. Later in this piece, we’ll explain in more detail how to work with that class and how to test your application on a Windows Phone 7. However, sometimes your application requires more than just a single location, it requires tracking movement, and you may need to test how your application behaves in different locations.

At these times, it may look odd to be driving around the block with your Windows Phone attached to a laptop while you try to debug your application.

Don’t worry—you’re in good hands. The Windows Phone GPS Emulator (a small WPF application) and one WP7 DLL enable you to debug your application on the Windows Phone emulator or a real device without leaving the comfort of your home or office. Once you’ve completed your testing and debugging, you only need to change a single line of code to switch to the device back to real GPS.

With the GPS Emulator, you can set a location anywhere on the globe by using the map display. Furthermore, you can plan routes with multiple intermediate waypoints, or use Bing services to calculate driving directions between locations. Once you’ve planned a route, you can simulate driving through the pre-defined waypoints along the path.

The recipe includes:

  • The Windows GPS Emulator application
  • The Windows Phone GPS Emulator Client DLL
  • A simple Windows Phone Test client
  • A complete end-to-end Windows Phone App using Bings maps (a more complex sample)

Using the GPS Emulator lets you create complex path that you can playback just as if you were driving or walking. Then, you can choose your Windows Phone application and receive the location information form the GPS Emulator just as if you got it via the real GPS.

image

 

Using GPS Emulator with your Windows Phone Application

But first thing first, let’s figure out how does the GPS Emulator helps you debug your Windows Phone client application?

When you download the Windows Phone GPS Emulator recipe, you’ll notice there is an assembly called GPSEmulatorClient. This DLL has a class called GeoCoordinateWatcher, which is the same name as the System.Device.Location.GeoCoordinateWatcher class, just in a different name space. This homebrew, “fake” GeoCoordinateWatcher class implements the IGeoPositionWatcher interface, which is the same interface that the “real” System.Device.Location.GeoCoordinateWatcher class implements. Therefore, we can say that the GPSEmulatorClient.GeoCoorinateWatcher implements the same API as the real System.Device.Location.GeoCoordinateWatcher. This means that both classes are transparent to the developer in terms using the location APIs. We added all the functions that are not defined by the IGeoPositionWatcher interface but are public in the System.Device.Location.GeoCoordinateWatcher class. As a result, you can write your application to use the GeoCoordinateWatcher and only change the initiation process based on your environment. You’ll need to add a reference to the GpsEmulatorClient as well as the using GpsEmulatorClient; statement.

In the GpsEmulatorPhoneTestClient application, we define the symbol by using the #define keyword. Next, in the MainPage constructor, we use the #if GPS_EMULATOR statement to distinguish between our testing environment and a real device, as shown in the next code snippet:

// This line has to be the first line in the file
#define GPS_EMULATOR // defining a compiler GPS symbol. 
 
// Init
IGeoPositionWatcher<GeoCoordinate> _Watcher;
#if GPS_EMULATOR
            _Watcher = new GpsEmulatorClient.GeoCoordinateWatcher();
#else
            _Watcher = new System.Device.Location.GeoCoordinateWatcher();
#endif

Since _Watcher is of type IGeoPositionWatcher<GeoCoordinate> both implementations—the real and the fake—can be casted to that variable. From this point on, it is simply a matter of using the GeoCoordinateWatcher method and properties to listen to location and status changes.

Working with the GeoCoordinateWatcher

As we said, the GeoCoordinateWatcher class is part of the System.Device.Location namespace. The GeoCoordinateWatcher class has the following properties:

  • DesiredAccurecy is of type GpsPositionAccurecy, which can be Default or High. High means the GPS readings are of high resolution, providing more accurate location (down to a few meters where possible). Note that High location resolution can shorten battery life.
    Note: One of the GeoCoordinateWatcher constructors has an input of GpsPositionAccuracy. By default it is set to Default, which means lower location resolution.
  • Permission is of type GeoPositionPermission, which defines the application’s level of access to the device. With Windows Phone you need to declare in your application manifest that you want to use the GPS device.
  • Position is of type GeoCoordinate and holds the current location, if the GPS status is valid.
  • Status is of type GpsPositionStatus, which indicates if the GPS readings are valid

There is one more property, MovementThreshold, which defines the minimum movement threshold, which by default is set to zero. You need to know that the GPS fires a lot of events, about one per second. That may not seem like a lot, but if you don’t move that fast or if your application doesn’t need to keep track at such a high resolution, make sure you set MovementThreshold to something other than zero. You can read more about this in a post by Jaime Rodriguez.

Next, you’ll want to register to the following events:

  • PositionChanged occurs when the location service detects a change in position, taking into account limitations like MovementThreshold
  • StatusChanged occurs when the status of the location service changes from Initializing to Ready, for example.

There’s not a lot more to it besides handling the events and updating your application accordingly. In our test sample, we simply read the values and print them on a screen, as shown in the next code snippet and image.

void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
     tbTimeAcquired.Text = e.Position.Timestamp.ToString();
     tbLatitude.Text = e.Position.Location.Latitude.ToString();
     tbLongtitude.Text = e.Position.Location.Longitude.ToString();
}

As you can see, the GeoPositionChangedEventArgs holds the position relevant to the location reading that triggered the PositionChanged event. The Position, which is of type GeoCoordinate class, includes, among other properties, Lat, Long, and time. It can include additional information, including VerticalAccuracy, altitude, speed, and more.

The output of our client application looks something like this:

image

The purple circle represents the current location transmitted by the Windows Phone GPS Emulator. It turns out that Microsoft building 24, where my office is located, is at Lat 47.6416 and Long -122.1306.

Follow a Few Rules

Before we dive into the technical details of the GPS Emulator, there are few rules you need to follow:

  • Run the GPS Emulator in Admin mode; it opens a WCF channel through which the Windows Phone application can read the location emulation.
  • Make sure the GPS Emulator runs before calling the GPSEmulatorClient.GeoCoordinateWatcher.Start method, as none of the demos really handles this scenario.
  • You’ll need to create a Bing Maps Account to fully access the power of the GPS Emulator. You can create an account here: http://www.bingmapsportal.com.
  • Remember to remove the #define GPS_EMULATOR symbol when testing on a real device.

The Windows Phone GPS Emulator is a great tool for testing your location-based Windows Phone applications without leaving the comfort of your home or office. But be sure you test your application on a real device, as location-based info or the lack of it could result in interesting edge cases in your application.

The Windows Phone GPS Emulator recipe includes detailed documentation including few samples and explanation on how the GPS emulator works.

Follow Windows Phone announcements on Twitter at WP7DEV

Follow Yochay on Twitter

Get started with free tools and free training

24 Comments
You must be logged in to comment. Sign in or Join Now
  • dawn99
    0 Posts

    Watching this thread with interest

    http://alertwatch.ie/

  • Anyone had any luck downloading the emulator? I can't get it to work!!

    <i>Always have security in mind and know a good <a href="www.d15locksmiths.com/.../i>

  • GPS Your Best Life- Release the brakes and get going!When you believe in yourself, you invite others to believe in you!” Have you ever noticed that sometimes the only person holding you back is you? Fear acts like brakes on a vehicle; it keeps you from moving ahead.

    www.mcmsecurity.com/gps-vehicle-satellite-tracking.html

  • The same happens to me, I couldn't download the recipe.

  • Oizen
    1 Posts

    Hi,

    I'm trying to download the gps emulator recipe but with no success. The download link takes me to the windows developer center and from there I don't know where to click and get the download. Please help I need to test my app's gps functionality

  • Anyone having issues with the GPSEmulatorClient.dll permission?  I keep getting a build error that it's blocked.

    I've made sure via the properties dialog box that the "Unblock" button is clicked...so it's then unblocked.  Tried to re-start Visual Studios again, but build keeps failing.

    Error 1 Could not load the assembly file:///C:\Users\Visitor\Documents\Visual Studio 2010\Projects\GPS\GPS\Bin\Debug\GpsEmulatorClient.dll. This assembly may have been downloaded from the Web.  If an assembly has been downloaded from the Web, it is flagged by Windows as being a Web file, even if it resides on the local computer. This may prevent it from being used in your project. You can change this designation by changing the file properties. Only unblock assemblies that you trust. See go.microsoft.com/fwlink for more information. GPS

  • Sab
    1 Posts

    Hi ,

    Am new to WP7..

    Is there an other option to find the location of the Emulator ?,because i find it unnecessary to include the whole GPSEmulator application in my project. I just need to plot the location of the device in the map...

    Thanks in Advance

  • rammeri
    1 Posts

    To run this on a German system (and fix the dreaded "no data")-issue, the easiest is to simply add the following line to App.xaml.cs (directly in the constructor for App()):

    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");

  • If GPSEmulator running and still ...GPS status: NoData!

    Try this!

    GPSEmulator/MainWindow.xaml.cs/line: 391

    string lat = currentPosition.X.ToString().Replace(",", ".");

    string lon = currentPosition.Y.ToString().Replace(",", ".");

    transmittedLocation = lat+","+lon;

  • @Yochay,

    Thanks for your comment on MovementThreshold , but I was actually referring to the device, not the emulator. I wanted to establish whether it controls how often the Position property is updated.

    Also I have a problem running the GPS Emulator at work. It complains that port 8192 is already in use. Some searching revealed that it may be Sophos Virus Protection and unfortunately I can't turn it off.

    Is there anyway to change the port number that the GPS Emulator uses?

  • ZIS
    1 Posts

    Hi,

    I am new in Windows Phone 7 development. I downloaded GpsEmulator.exe.    "ArgumentNullEcxeption was unhandled" occured on Emulator.   I am working on application that gives the current position (Lat Long) of the device and draw an arrow between the current position and destination. Any help

    Thanks.

  • lyano
    1 Posts

    Hi

    it does not work for me. Wpf application says " client connected" but in my wp7 application i only get "no data" as status for the watcher. Any idea about where the problem could be?

  • Hi

    This looks perfect for what I need at the moment, but I cant seem to get it to work.

    Ive download the samples but when I run the gpsemulator.exe it just starts and then exits. I've read through the notes and cant find any details of what isnt working.

    I'm sure its just me being daft, but i've no idea whats going on.

    Any ideas?

    Thanks

  • Gaploid
    6 Posts

    And its finnally it does not work. Even a test application shows only "NoData" but wpf application said that the clien is connected=( I`ve start application under admin rights on Windows 7.

  • Gaploid
    6 Posts

    Sometime WPF application craches with this error:

    Application: GpsEmulator.exe

    Framework Version: v4.0.30319

    Description: The process was terminated due to an unhandled exception.

    Exception Info: System.Windows.Markup.XamlParseException

    Stack:

      at System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri)

      at System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri)

      at System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader, Boolean, System.Object, System.Xaml.Permissions.XamlAccessLevel, System.Uri)

      at System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream, System.Windows.Markup.ParserContext, System.Object, Boolean)

      at System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream, System.Windows.Markup.ParserContext)

      at System.Windows.Application.LoadComponent(System.Uri, Boolean)

      at System.Windows.Application.DoStartup()

      at System.Windows.Application.<.ctor>b__1(System.Object)

      at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)

      at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)

      at System.Windows.Threading.DispatcherOperation.InvokeImpl()

      at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)

      at System.Threading.ExecutionContext.runTryCode(System.Object)

      at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)

      at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

      at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)

      at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

      at System.Windows.Threading.DispatcherOperation.Invoke()

      at System.Windows.Threading.Dispatcher.ProcessQueue()

      at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)

      at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)

      at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)

      at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)

      at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)

      at System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)

      at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)

      at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)

      at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)

      at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)

      at System.Windows.Threading.Dispatcher.Run()

      at System.Windows.Application.RunDispatcher(System.Object)

      at System.Windows.Application.RunInternal(System.Windows.Window)

      at System.Windows.Application.Run(System.Windows.Window)

      at System.Windows.Application.Run()

      at GpsEmulator.App.Main()

  • @Morten Nielsen: Thanks, your comment on the culturinfo made the emulator work for me.

  • @Odegaard - Thank you for your comments. Most are great and it looks like we can improve the GIS Emulator, which we'll do.

    Per your comment about #define approach. The reason we use #define, is to enable the GPS to work on a real device and not just the emulator.

  • Here's how to get Speed and Heading in as well.

    GpsEmulator\Mainpage.Xaml.cs line 391: replace the "transmittedLocation = ..." line with:

    double heading = 90 - Math.Atan2(dLat, dLng) * 180 / Math.PI;

    if(heading < 0) heading += 360;

    transmittedLocation = String.Format(System.Globalization.CultureInfo.InvariantCulture,

    "{0}, {1}, {2}, {3}", currentPosition.X, currentPosition.Y, simulationSpeed, heading);

    In GpsEmulatorClient\GeoCoordinateWatcher.cs, line 249: Replace with if section with:

    if (coordinates.Length >= 2)

    {

       double lat, lng;

    double heading = 0;

    double speed = 0;

    if (coordinates.Length > 2)

    double.TryParse(coordinates[2], out speed);

    if (coordinates.Length > 3)

    double.TryParse(coordinates[3], out heading);

       if (Double.TryParse(coordinates[0], out lat) && double.TryParse(coordinates[1], out lng))

       {

           GeoCoordinate gc = new GeoCoordinate(lat, lng);

           if (_PrevGc == null || !_PrevGc.Equals(gc))

           {

               _PrevGc = gc;

               currentLocation = new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, gc);

    currentLocation.Location.Course = heading;

    currentLocation.Location.Speed = speed;

               GeoPositionChangedEventArgs<GeoCoordinate> gpcea =

    new GeoPositionChangedEventArgs<GeoCoordinate>(currentLocation);

    Status = GeoPositionStatus.Ready;

               OnPositionChanged(gpcea);

           }

       }

    }

    Note though: The defaultSpeed value is NOT the correct speed. The simulator seems to be using a value MUCH MUCH MUCH faster than this speed. As far as I can tell, the only thing the speed is used for, is for parsing to Bing.

    The value the emulator is using has really nothing to do with speed.

    For a more more "consistent" speed and event trigger that better simulates a drive, see my drive simulator I presented here: www.sharpgis.net/.../Simulating-GPS-on-Windows-Phone-7.aspx It has all the spherical trigonometry required to do this right.

    Combine this approach with this emulator, and I think we got a winner.

  • While this is a good start, the main problems I see with this implementation that makes it hard to use in any real life testing is:

    1. Updates are WAY too frequent. GPS updates ~1/sec, and this app should do the same, instead of as fast as possible. It will be misleading in the test sample, and put a lot more load on the test app than normally would happen (depending on how much processing is done per location update).

    2. Speed and Heading is not transmitted. This is cruzial in many apps.

    3. Accuracy is not simulated and transmitted. I need to be able to set some accuracy, and it should randomize the location within that accuracy. Accuracy should likewise be transmitted to client. WIthout this, comparing to "real life" scenarios where you often get poor data is hard to test. (of course an option to disable randomizing and get 0m accuracy would be fine for some testing scenarios).

    4. No altitude value at all.

    5. This one is REALLY bad: You don't use CultureInfo.Invariant on to and from string parsing, so the transmit will fail in many regions. Any code analyzer would have caught this.

    6. As many people pointed out, MovementThreshhold is not implemented. Considering its even mentioned in this blogpost makes it really weird that this is left out.

  • Instead of using the #define approach I like this better:

    string deviceName = Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("DeviceName").ToString();

    if (deviceName == "XDeviceEmulator") //Always use simulator on emulator

    {    /*create emulator*/   }

    else { /*create GeocoordinateWatcher*/ }

    That way I always have a GPS Emulator on my WinPhone Emulator, and use the real GPS signal on the device.

  • Hi Yochay,

    I can't set the movementthreshold without getting an error. I am OK with it not being implemented, but I have to comment it out, and then remember to uncomment it for the device

    Thanks

    Pete

  • @petevick, and @ JasonBSteele,

    The MovementThreshold is not implemented in the GPS Emulator. You can set it, but nothing really happens... The comment about it in the post, was to gives you heads-up on what might happen.

  • This is really useful... many thanks for making my life easier!

    Another question on MovementThreshold, does it also control how often the Position property is updated?

    Thanks

  • Hi,

    great addition - will help testing a lot.

    One question, how do I use MovementThreshold as it doesn't seem to be supported

    Thanks