MOBILE

Windows Phone 7 Development : Using Location Services - Simulating the Location Service

2/28/2011 10:53:45 AM
In order to simulate use of the location service, you will be intercepting the GeoCoordinateWatcher's PositionChanged event using an Observable object. With an Observable object, you can subscribe to an event and then stream the data received to the subscribed event delegates. For the examples in this artcile, you will subscribe to the PositionChanged event to feed GPS data to the parts of your application that consume it.

1. Creating the GeoCoordinateWatcherDemo Project

In order to use the .NET Reactive Extension, you will need to add a reference to Microsoft.Phone.Reactive. You'll also need to reference System.Device in order to use the location service and, most importantly, System.Observable, in order to feed GPS data to the location service.

  1. Open Microsoft Visual Studio 2010 Express for Windows Phone on your workstation.

  2. Create a new Windows Phone Application by selecting File => New Project on the Visual Studio command menu. Select the Windows Phone Application template, and name the application "GeoCoodinateWatcherDemo."

  3. Add a reference to Microsoft.Phone.Reactive in order to use Reactive Extension. Also add a reference to System.Device in order to use the location service. In Solution Explorer, you should be able to see the added reference as shown in Figure 1.

Figure 1. Project references to use the Reactive Extension and the location service

2. Coding the User Interface

You will be building the user interface using the XAML in the Visual Studio. For building simple controls, it is faster to work with the XAML code. Go to the solution, open MainPage.xaml, and replace the XAML you find there with the following codes.

2.1. Declaring the UI Resources

The namespaces you see in the following code snippet are typically declared by default when you first create a Windows Phone project. In particular, namespaces xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" allow you to add common Windows Phone controls to the application main page.

<phone:PhoneApplicationPage
x:Class="GeoCoordinateWatcherDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">


2.2. Building the Main Page and Adding Components

Now add two textblocks, txtLatitude and txtLongitude, to display the longitude and latitude that the phone location service provides.

<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="GeoCoordinateWatcherDemo"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBox Height="72" Name="txtLongitude" Text=""
Margin="193,142,41,393" />
<TextBox Height="72" Name="txtLatitude" Text=""
Margin="193,236,41,299" />
<TextBlock Height="30" HorizontalAlignment="Left"
Margin="78,202,0,0" Name="textBlock1"
Text="Longitude" VerticalAlignment="Top" />


<TextBlock Height="30" HorizontalAlignment="Left"
Margin="78,306,0,0" Name="textBlock2"
Text="Latitude" VerticalAlignment="Top" />
</Grid>
</Grid>
</phone:PhoneApplicationPage>

Once you have loaded the XAML code, you should see the layout shown in Figure 2. In the next section, you will be adding events to handle updating the UI with the received GPS data from the location service.

Figure 2. GeoCoordinateWatcherDemo design view

3. Coding the Application

In Solution Explorer, open MainPage.xaml.cs and replace the code there with the following C# code blocks, which will implement the UI updates using the location service with the data received from Reactive Extension.

3.1. Specifying the Namespaces

Begin by listing the namespaces the application will use. You will need System.Device.Location in order to use the location service. Declare Microsoft.Phone.ReactiveSystem.Threading in order to feed the GPS data into the location service; you can think of Reactive Extension's Observable as if it were the satellite, Wi-Fi, or communication tower sending the GPS data. in order to use the Reactive Extension's Observable. Also note that you will need

using Microsoft.Phone.Controls;
using System.Threading;
using Microsoft.Phone.Reactive;
using System.Device.Location;
using System.Collections.Generic;
using System;

3.2. Initializing Variables

The variable _geoCoordinateWatcher is an instance of the Windows Phone location class that you'll use to access and retrieve location data. Notice in the constructor we declared the PositionChanged event in order to receive the location service's GPS data. Also you will be starting the thread that will simulate the GPS data that is sent to the PositionChanged event delegate.

GeoCoordinateWatcher _geoCoordinateWatcher;

public MainPage()
{
InitializeComponent();

// initialize GeoCoordinateWatcher
_geoCoordinateWatcher = new GeoCoordinateWatcher();

// PositionChanged event will receive GPS data
_geoCoordinateWatcher.PositionChanged +=
new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>
(_geoCoordinateWatcher_PositionChanged);

// simulateGpsThread will start Reactive Extension
// where EmulatePositionChangedEvents will be feeding
// the data to PositionChanged event
Thread simulateGpsThread = new Thread(SimulateGPS);
simulateGpsThread.Start();
}


3.3. Simulating GPS Data Using Reactive Extension's Observable

In the foregoing constructor, you initiated a thread that executes the SimulateGPS method. In the SimulateGPS method, the Reactive Extension's ObservablePositionChanged event in order to feed the GPS data. Notice that GPSPositionChangedEvents constantly sends GeoPositionChangedEventArgsPositionChanged event and the GPS data. subscribes to the every two seconds, which then gets received by GeoCoordinateWatcher's

// Reactive Extension that intercepts the _geoCoordinateWatcher_PositionChanged
// in order to feed the GPS data.
private void SimulateGPS()
{
var position = GPSPositionChangedEvents().ToObservable();
position.Subscribe(evt => _geoCoordinateWatcher_PositionChanged(null, evt));
}

private static IEnumerable<GeoPositionChangedEventArgs<GeoCoordinate>>
GPSPositionChangedEvents()
{
Random random = new Random();

// feed the GPS data
while (true)
{
Thread.Sleep(TimeSpan.FromSeconds(2));

// randomly generate GPS data, latitude and longitude.
// latitude is between −90 and 90
double latitude = (random.NextDouble() * 180.0) − 90.0;
// longitude is between −180 and 180
double longitude = (random.NextDouble() * 360.0) − 180.0;
yield return new GeoPositionChangedEventArgs<GeoCoordinate>(
new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, new
GeoCoordinate(latitude, longitude)));
}
}


3.4. Displaying GPS Data

In this demo, the received GPS data is displayed directly to the user. Notice here that you are using Dispatcher.BeginInvoke to execute the lamda expression of an anonymous method. Using Dispatcher.BeginInvoke to update the UI with the GPS data is absolutely necessary because the PositionChanged event is executed in a different thread than the UI, and thus you must explicitly use Dispatcher.Invoke to run UI specific codes.

private void _geoCoordinateWatcher_PositionChanged(object sender
, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
this.Dispatcher.BeginInvoke(() =>
{
txtLatitude.Text = e.Position.Location.Latitude.ToString();
txtLongitude.Text = e.Position.Location.Longitude.ToString();
});
}


4. Testing the Finished Application

To test the application, press F5. The result should resemble the screenshot in Figure 3, and you will see constantly changing longitude and latitude in the textblocks.

Figure 3. GeoCoordinateWatcherDemo
Other  
  •  Introducing the Windows Phone Location Service and Mapping APIs
  •  iPhone Application Development : Implementing a Custom Picker View (part 4) - Tweaking the Picker UI
  •  iPhone Application Development : Implementing a Custom Picker View (part 3) - Reacting to a Picker View Choice
  •  iPhone Application Development : Implementing a Custom Picker View (part 2)
  •  iPhone Application Development : Implementing a Custom Picker View (part 1)
  •  Windows Phone 7 Development : Isolated Storage - Working with Isolated Storage Settings
  •  Mobile Application Security : WebOS Security - Permissions and User Controls
  •  Mobile Application Security : WebOS Security - Code Security
  •  Windows Phone 7 Development : Working with Isolated Directory Storage (part 2)
  •  Windows Phone 7 Development : Working with Isolated Directory Storage (part 1)
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 3)
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 2) - Adding a Date Picker
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 1)
  •  iPhone Application Development : Making Multivalue Choices with Pickers - Understanding Pickers
  •  Sync Your iPad with iTunes : Troubleshooting iTunes and the Sync
  •  Sync Your iPad with iTunes : Manually Transferring Music, Movies, Podcasts, and More on Your iPad (Drag-and-Drop Method)
  •  Windows Phone 7 Development : Internationalization - Using Resource Files to Localize Content
  •  Windows Phone 7 Development : Internationalization - Storing and Retrieving Current Culture Settings
  •  Mobile Application Security : WebOS Security - Development and Security Testing
  •  Mobile Application Security : WebOS Security - Introduction to the Platform
  •  
    Top 10
    Building Out Of Browser Silverlight Applications - Controlling the Application Window
    Exchange Server 2010 : Maintaining Reliability and Availability - Recover Data
    jQuery 1.3 : Table Manipulation - Sorting and paging (part 1) : Server-side sorting & JavaScript sorting
    jQuery 1.3 : Developing plugins - Adding new global functions
    SQL Server 2008 : Programming Objects - Implementing Stored Procedures
    Windows Azure : Messaging with the queue - Decoupling your system with messaging
    Tools to Manage Access Control Lists
    Mobile Application Security : The Apple iPhone - Local Data Storage: Files, Permissions, and Encryption
    Design and Deploy High Availability for Exchange 2007 : Create Bookmark Create Note or Tag Implement Standby Continuous Replication (SCR)
    Deploying the Client for Microsoft Exchange Server 2010 : Pushing Outlook Client Software with Group Policies
    Most View
    ASP.NET 4 in VB 2010 : The Security Controls
    iPhone 3D Programming : Adding Textures to ModelViewer (part 4) - Enabling Textures with ES2::RenderingEngine
    Outlining AD DS Changes in Windows Server 2008 R2 (part 3) - Auditing Changes Made to AD Objects
    SharePoint 2010 : SQL Server Database Mirroring for SharePoint Farms
    Building LOB Applications : Data Validation through Data Annotation
    Navigating Architecture Changes in Windows Vista
    iPhone 3D Programming : Adding Depth and Realism - Shaders Demystified
    jQuery 1.3 : Modifying table appearance (part 2) - Tooltips
    Design and Deploy High Availability for Exchange 2007 : Design Edge Transport and Unified Messaging High Availability
    Personalizing Windows 7 (part 3) - Choosing and Configuring Your Screensaver
    SQL Server 2008 : Service Broker - Message Types
    Designing and Implementing Mobility in Exchange Server 2010 : Securing Access to ActiveSync Using Internet Security and Acceleration (ISA) Server 2006
    SQL Server 2008 : What Is the Base Class Library?
    Creating and Managing Views in SQL Server 2008 : Creating Views
    Examining Integration Points Between SharePoint and Public Key Infrastructure
    jQuery 1.3 : Modifying table appearance (part 3) - Collapsing and expanding sections
    Advanced ASP.NET : Creating a Component
    Installing SharePoint 2010 Using PowerShell
    iPhone 3D Programming : Holodeck Sample (part 4) - Replacing Buttons with Orientation Sensors
    iPhone 3D Programming : Reflections with Cube Maps