Windows Phone 8.1 comes with a lot of prospects in the geo location end and usually the next thing after detecting your very own location, people tends to look for one another thing and that is tracking the location as it should update itself. So, if you’re wondering about how you should instantiate a map and track your location, you really should check out my previous post .
And if you have already done that (I hope you liked it). Then you’d probably know how to do the following:
- Please go ahead to your visual studio (Im using a Visual Studio 2013 Community Edition) and open a new project on Blank App on Windows Phone 8.1
- Go over your project properties and go over Capabilities. Enable Location for your app (If you are from Windows Phone 8, you’d be pretty amazed that you don’t see ID_CAP_MAP anymore.
A Basic UI:
Let’s set up a basic UI and yes It’s kind of a rip off from MSDN but as long as it helps people, it’s cool. Our little UI has two Buttons and a number of textblocks and it looks like below in XAML (I’m only posting the main grid):
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid> <TextBlock Text="Location Tracker" Margin=" 15" FontSize="45"></TextBlock> </Grid> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Button Grid.Column="0" Content="Track Location" Click="TrackLocationButton_Click" HorizontalAlignment="Center" x:Name="TrackLocationButton" VerticalAlignment="Bottom" /> <Button IsEnabled="False" Grid.Column="1" Content="Stop Tracking" Click="StoptrackingButton_Click" HorizontalAlignment="Center" x:Name="StoptrackingButton" VerticalAlignment="Bottom" /> </Grid> <Grid Grid.Row="2"> <Grid.ColumnDefinitions> <ColumnDefinition Width="3.5*"></ColumnDefinition> <ColumnDefinition Width="7*"></ColumnDefinition> </Grid.ColumnDefinitions> <StackPanel Margin="10"> <TextBlock Text="Latitude" FontSize="23" /> <TextBlock Text="Longitude" FontSize="23" /> <TextBlock Text="Accuracy" FontSize="23" /> </StackPanel> <StackPanel Margin="10" Grid.Column="1"> <TextBlock Name="LatitudeText" FontSize="23" /> <TextBlock Name="LongitudeText" FontSize="23" /> <TextBlock Name="AccuracyText" FontSize="23" /> </StackPanel> </Grid> </Grid>
If that seems a bit too much xaml for you then calm down because It looks extremely basic too:
Now, let’s move towards the MainPage.xaml.cs part. As the previous article suggests, the first thing you need is definitely a Geolocator . So please go ahead and define a Geolocator instance.
private Geolocator locator = null;
Now that we have a geo locator we can move ahead and go over the Properties of TrackLocationButton and create the method stub for Click event. And the event handler looks like below:
private void TrackLocationButton_Click(object sender, RoutedEventArgs e) { if (locator == null) { locator = new Geolocator(); } if (locator != null) { locator.MovementThreshold = 3; locator.PositionChanged += new TypedEventHandler<Geolocator, PositionChangedEventArgs>(locator_PositionChanged); } TrackLocationButton.IsEnabled = false; StoptrackingButton.IsEnabled = true; }
Now, if you dive a little bit into that, you will see that if the locator is instantiated then the first property we do change is the MovementThreshold property. It is the property that defines the movement threshold for the geo tracking to notify you. It’s defined in meters and thus we have defined it to 3 meters. Now next question that comes along is how would I know that I have moved my MovementThreshold amount of distance. The common answer would be actually invoking a PositionChanged event and attach a handler to it. And the handler locator_PositionChanged looks like below:
async private void locator_PositionChanged(Geolocator sender, PositionChangedEventArgs e) { await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Geoposition geoPosition = e.Position; LatitudeText.Text = geoPosition.Coordinate.Point.Position.Latitude.ToString(); LongitudeText.Text = geoPosition.Coordinate.Point.Position.Longitude.ToString(); AccuracyText.Text = geoPosition.Coordinate.Accuracy.ToString(); }); }
Now even before describing whats being done here you might wonder where the dispatcher comes from, truth is it has been declared before as:
private Geolocator locator = null; private CoreDispatcher dispatcher; public MainPage() { this.InitializeComponent(); dispatcher = Window.Current.CoreWindow.Dispatcher; }
The reason we are using that would be pretty clear if we look at what are we doing. We are constantly updating our LatitudeText, LongitudeText, AccuracyText and as we are accessing a UI thread frequently from a event handler, we do need to make it sure it doesn’t block the regular UI interactions. Thus we used a CoreDispatcher here, much like it was in Windows Phone 8 as Dispatcher. You’d also be able to notice that the event handler is async and thus dispatcher.RunAsync invocation was awaited. We used CoreDispatcherPriority.Normal and you can even try a higher priority if you like. All this event handler is doing is it is actually updating the UI and the textblocks.
Now all you need is a StoptrackingButton to get things to stop and all you have to do is unhook the locator_PositionChanged event handler.
private void StoptrackingButton_Click(object sender, RoutedEventArgs e) { if (locator != null) { locator.PositionChanged -= new TypedEventHandler<Geolocator, PositionChangedEventArgs>(locator_PositionChanged); } StoptrackingButton.IsEnabled = false; TrackLocationButton.IsEnabled = true; }
Debugging it on the emulator:
As this sample has geolocator usage, this is always better to be tested in a device but you can definitely try it on an emulator too. To test it load the app on the emulator first by invoking build.
When the emulator hooks up open up the emulator tools and go to the location tab and click on the map to give you a primary location first. You can have a look at the gif below for an idea
Now after you pointed a primary location in the map. Now you can try clicking the track location button. After you do that Latitude, Longitude and Accuracy would pop up for the place you clicked on the map. Now click some more around it. And you will see the data changes on the textblocks. You can do one thing more too. You can change the interaction mode from Live to Pin and play all the pins. That would even allow to emulate place changes in your emulator. The following gif would definitely help you.
And the code sample is here.
Stay Frosty!