Adam Benoit

Windows Phone Development

Continuous Location tracking on Windows Phone 8

Posted on

by Adam

While digging through the Windows Phone 8 SDK docs, I noticed that the Location services seem to have changed to include an option for tracking the handsets location on a continuous basis. It is marked in the docs as new to WP8 so I thought I would share a sample.

Source is available here.

We start with the MainPage.xaml view:

 <phone:PhoneApplicationPage
    x:Class="ContinuousLocation.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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock Text="{Binding Path=LocalizedResources.PageTitle, Source={StaticResource LocalizedStrings}}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
                <Button x:Name="TrackLocationButton" Click="TrackLocation_Click" Content="track location"/>
                <TextBlock x:Name="LatitudeTextBlock"/>
                <TextBlock x:Name="LongitudeTextBlock"/>
                <TextBlock x:Name="StatusTextBlock"/>
            </StackPanel>
        </Grid>
   </Grid>
</phone:PhoneApplicationPage>

The following code is pulled almost directly the SDK documentation. I tested it in the emulator and found it works well.

using System.Windows;
using Microsoft.Phone.Controls;
using Windows.Devices.Geolocation;

namespace ContinuousLocation
{
    public partial class MainPage : PhoneApplicationPage
    {
        Geolocator geolocator = null;
        bool tracking = false;

        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
        private void TrackLocation_Click(object sender, RoutedEventArgs e)
        {
            if (!tracking)
            {
                geolocator = new Geolocator();
                geolocator.DesiredAccuracy = PositionAccuracy.High;
                geolocator.MovementThreshold = 100; // The units are meters.

                geolocator.StatusChanged += geolocator_StatusChanged;
                geolocator.PositionChanged += geolocator_PositionChanged;

                tracking = true;
                TrackLocationButton.Content = "stop tracking";
            }
            else
            {
                geolocator.PositionChanged -= geolocator_PositionChanged;
                geolocator.StatusChanged -= geolocator_StatusChanged;
                geolocator = null;

                tracking = false;
                TrackLocationButton.Content = "track location";
                StatusTextBlock.Text = "stopped";
            }
        }

        void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
        {
            Dispatcher.BeginInvoke(() =>
            {
                LatitudeTextBlock.Text = args.Position.Coordinate.Latitude.ToString(  "0.00000000");
                LongitudeTextBlock.Text = args.Position.Coordinate.Longitude.ToString("0.00000000");
            });
        }

        void geolocator_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
        {
            string status = "";

            switch (args.Status)
            {
                case PositionStatus.Disabled:
                    // the application does not have the right capability or the location master switch is off
                    status = "location is disabled in phone settings";
                    break;
                case PositionStatus.Initializing:
                    // the geolocator started the tracking operation
                    status = "initializing";
                    break;
                case PositionStatus.NoData:
                    // the location service was not able to acquire the location
                    status = "no data";
                    break;
                case PositionStatus.Ready:
                    // the location service is generating geopositions as specified by the tracking parameters
                    status = "ready";
                    break;
                case PositionStatus.NotAvailable:
                    status = "not available";
                    // not used in WindowsPhone, Windows desktop uses this value to signal that there is no hardware capable to acquire location information
                    break;
                case PositionStatus.NotInitialized:
                    // the initial state of the geolocator, once the tracking operation is stopped by the user the geolocator moves back to this state

                    break;
            }

            Dispatcher.BeginInvoke(() =>
            {
                StatusTextBlock.Text = status;
            });
        }
    }
}

Now the final step is to enable thelocation capability in the WMAppManifest.xml file:

And now when you run it in the emulator, you click the button and the coordinates are displayed. Opening the Location tab of the tools and click on a map location, the app displays the new location in a moment.

About Adam

Adam Benoit is a Quality Assurance Analyst, Contributing Author and Windows Phone Developer. View all posts by Adam →
This entry was posted in Development, Featured, Howto and tagged , , , , . Bookmark the permalink.

10 Responses to Continuous Location tracking on Windows Phone 8

  1. How is that different from WP7’s GeoCoordinateWatcher? (http://msdn.microsoft.com/en-us/library/system.device.location.geocoordinatewatcher.aspx)
    I kinda hope that GeoLocator can be used to get precise location from a background agent, but you haven’t tested that.

    • Adam

      This is the new way for WP8 devices to get the location continuously. The existing method is still supported but the docs state that this is capable of running in the background by modifying the DefaultTask in the WMAppManifest.xml file to the following:

      <DefaultTask Name=”_default” NavigationPage=”MainPage.xaml”>
      <BackgroundExecution>
      <ExecutionType Name=”LocationTracking” />
      </BackgroundExecution>
      </DefaultTask>

      Then adding RunningInBackground=”Application_RunningInBackground” to the shell:PhoneApplicationService element in the App.xaml file.

      Then you can add the Application_RunningInBackground handler:

      private void Application_RunningInBackground(object sender, RunningInBackgroundEventArgs args)
      {
      // Suspend all unnecessary processing such as UI updates
      }

      now the app will continue tracking in the background.

  2. Pingback: Continuous Location tracking on Windows Phone 8 | azkafaiz.com

  3. Pingback: Continuous Location tracking on Windows Phone 8

  4. Pingback: Continuous Location tracking on Windows Phone 8 Part 2: Background | Adam Benoit

  5. Sergey

    Thank you very much – I was seaching for this example for the whole day!

  6. I think ”backgroundtask” tag in app.xaml seems to be available only for windows apps and not available for 3rd party apps.
    So how can I use it in my app?

  7. Yes. It works. Sorry my bad. I had done a small mistake in code.