How to run location-tracking apps in the background for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

This topic shows you how to create a location-tracking app that runs in the background. For information on apps that run in the background, including best practices and feature limitations, see Running location-tracking apps in the background for Windows Phone 8.

The following tasks for creating a location-tracking app that runs in the background are shown in this topic.

  1. Modify the app manifest file to enable background execution.

  2. Implement a handler for the RunningInBackground event. This event is raised when the user navigates away from your background execution-enabled app while you are actively tracking location. When this event is raised, your app should stop all tasks that are not related to location tracking, including updates to the app’s UI. For a list of Windows Phone APIs that can be used during background execution, see Features that can be used while running in the background for Windows Phone 8.

Important Note:

To use the Location API in your app, you must include in the ID_CAP_LOCATION capability in your app manifest file. If you don’t do this, your app will throw an exception when you deploy it during development, and your app will fail ingestion when you submit it to the Windows Phone Store. For more information about app capabilities for Windows Phone, see App capabilities and hardware requirements for Windows Phone 8.

Enabling a location-tracking app to run in the background

  1. Create a new Windows Phone app.

  2. Add the ID_CAP_LOCATION to the app manifest XML file. In Solution Explorer, expand the Properties folder, and then double-click WMAppManifest.xml. On the Capabilities tab of the manifest designer, select the check box next to ID_CAP_LOCATION.

  3. Enable background execution by modifying the app manifest file. For this task, you need to edit the app manifest directly instead of using the manifest editor. To do this, right-click WMAppManifest.xml, click Open with, and then choose XML (Text) Editor.

  4. Overwrite the DefaultTasks element with the following code.

    <DefaultTask Name="_default" NavigationPage="MainPage.xaml">
      <BackgroundExecution>
        <ExecutionType  Name="LocationTracking" />
      </BackgroundExecution>
    </DefaultTask>
    
  5. In App.xaml, overwrite the shell:PhoneApplicationService element with the following code. This registers an event handler for the RunningInBackground event.

    <shell:PhoneApplicationService 
        Launching="Application_Launching" Closing="Application_Closing" 
        Activated="Application_Activated" Deactivated="Application_Deactivated"
        RunningInBackground="Application_RunningInBackground"/>
    
  6. In App.xaml.cs, add a declaration to use the Windows.Devices.Geolocation namespace.

  7. In App.xaml.cs, declare some static variables that will be global to the application. These include a Geolocator object that can be shared between pages and a boolean variable, RunningInBackground, that will be used to track if the app is running in the background or in the foreground. This enables the app to suspend unnecessary tasks, like updating the UI, while it is running in the background.

    public static Geolocator Geolocator { get; set; }
    public static bool RunningInBackground { get; set; }
    
  8. In App.xaml.cs, add the RunningInBackground event handler. This event is raised when the user navigates away from your app while it is actively tracking location and your app begins to run in the background. In this event handler, the RunningInBackground global variable is set to true.

    private void Application_RunningInBackground(object sender, RunningInBackgroundEventArgs args)
    {
        RunningInBackground = true;
        // Suspend all unnecessary processing such as UI updates
    }
    
  9. In App.xaml.cs, update the Application_Activated method to set the RunningInBackground global variable back to false. If your app is running in the background and the user launches your app, such as by tapping your app’s Start tile, this method, which is the handler for the Activated event, is called. At this point, your app should resume foreground tasks like updating the UI.

    private void Application_Activated(object sender, ActivatedEventArgs e)
    {
        RunningInBackground = false;
    }
    
  10. When a location app is running in the background, it handles app relaunch in a slightly different way from standard apps. This example app uses two pages so that you can see how this works. The first page will just link to the second page, which will implement the location tracking. In MainPage.xaml, replace the Grid element named “ContentPanel” with the following code. This adds a HyperlinkButton that will navigate to the app’s other page.

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <HyperlinkButton NavigateUri="/Page2.xaml" Content="go to page 2"/>
    </Grid>
    
  11. Add a second page to the app by going to the Project menu and clicking Add New Item… and then selecting Windows Phone Portrait Page. Name the new page “Page2.xaml”.

  12. In Page2.xaml, replace the Grid element named “ContentPanel” with the following code. This adds two TextBlock controls to display the latitude and longitude when the app is in the foreground.

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <StackPanel>
            <TextBlock x:Name="LatitudeTextBlock" Text="latitude"/>
            <TextBlock x:Name="LongitudeTextBlock" Text="longitude"/>
        </StackPanel>
    </Grid>
    
  13. Override the OnNavigatedTo(NavigationEventArgs) method to initialize the Geolocator object if it is not already initialized and to hook up the event handler for the PositionChanged event. You could also hook up the StatusChanged event here. Paste the following method into Page2.xaml.cs.

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        if (App.Geolocator == null)
        {
            App.Geolocator = new Geolocator();
            App.Geolocator.DesiredAccuracy = PositionAccuracy.High;
            App.Geolocator.MovementThreshold = 100; // The units are meters.
            App.Geolocator.PositionChanged += geolocator_PositionChanged;
        }
    }
    
  14. In Page2.xaml.cs, add an override of the OnRemovedFromJournal(JournalEntryRemovedEventArgs) method. This method is called when the page is removed from the app’s journal. This means that if the app ever shows this page again, a new instance will be created. In this method, remove the event handler and set the Geolocator to null.

    protected override void OnRemovedFromJournal(System.Windows.Navigation.JournalEntryRemovedEventArgs e)
    {
        App.Geolocator.PositionChanged -= geolocator_PositionChanged;
        App.Geolocator = null;
    }
    
  15. Implement the PositionChanged event handler. Check the value of the global variable RunningInBackground. If the value is false, then the app is in the foreground, and BeginInvoke(Action) is used to update the text blocks on the UI thread with the current location. If the value is true, then the app is running in the background. The UI should not be updated. Instead, in this example, a ShellToast with the current location is launched. The NavigationUri of the toast is set to the Page2.xaml. This Uri will be used to illustrate the app’s page management behavior when it is relaunched.

    void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
    {
    
        if (!App.RunningInBackground)
        {
            Dispatcher.BeginInvoke(() =>
            {
                LatitudeTextBlock.Text = args.Position.Coordinate.Latitude.ToString("0.00");
                LongitudeTextBlock.Text = args.Position.Coordinate.Longitude.ToString("0.00");
            });
        }
        else
        {
            Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast();
            toast.Content = args.Position.Coordinate.Latitude.ToString("0.00");
            toast.Title = "Location: ";
            toast.NavigationUri = new Uri("/Page2.xaml", UriKind.Relative);
            toast.Show();
    
        }
    }
    

See Also

Other Resources

Running location-tracking apps in the background for Windows Phone 8

Features that can be used while running in the background for Windows Phone 8