Introduction to the Geolocation API

The Windows Runtime (WinRT) Geolocation API allows your UWP applications to access the location of the device. This can be used to provide location-aware services, such as displaying the user's current position on a map, finding nearby points of interest, or personalizing content based on location.

This API leverages hardware sensors like GPS, Wi-Fi positioning, and cellular triangulation to determine the most accurate location possible. It's important to handle user privacy and obtain consent before accessing location data.

Core Concepts

  • Geolocator: The primary class used to request and track the device's location.
  • Geoposition: Represents a single position reading, containing latitude, longitude, accuracy, and other details.
  • CivicAddress: Provides human-readable address information associated with a geoposition.
  • PositionAccuracy: Defines the level of accuracy required for a location request.
  • PositionStatus: Indicates the current status of the geolocation service.

Classes and Interfaces

Windows.Devices.Geolocation.Geolocator

This is the main entry point for accessing location data. You can use it to request a single location reading or to receive updates when the location changes.

Properties:

  • DesiredAccuracy: (PositionAccuracy) The desired accuracy of the location data.
  • MovementThreshold: (Double) The minimum distance in meters a device must move before a PositionChanged event is raised.
  • ReportInterval: (UInt32) The desired interval in milliseconds between location updates.
  • LocationStatus: (PositionStatus) The current status of the geolocation service.

Methods:

  • GetGeopositionAsync(): Retrieves a single geolocated position.
  • GetGeopositionAsync(UInt64, UInt64): Retrieves a single geolocated position with specified timeout and maximum age.
  • StartListening(): Starts listening for location changes.
  • StopListening(): Stops listening for location changes.

Events:

  • PositionChanged: Raised when the device's location changes.
  • StatusChanged: Raised when the status of the geolocation service changes.
// Example: Getting a single location reading
var geolocator = new Geolocator();
geolocator.DesiredAccuracy = PositionAccuracy.High;
Geoposition geoposition = await geolocator.GetGeopositionAsync();
double latitude = geoposition.Coordinate.Latitude;
double longitude = geoposition.Coordinate.Longitude;

Windows.Devices.Geolocation.Geoposition

Represents a geographical position.

Properties:

  • Coordinate: (Geocoordinate) The geocoordinate information.
  • Civic: (CivicAddress) The civic address information.
  • Accuracy: (UInt32) The accuracy of the position in meters.
  • Timestamp: (DateTime) The time at which the position was determined.

Windows.Devices.Geolocation.Geocoordinate

Contains detailed coordinate information.

Properties:

  • Latitude: (Double) The latitude in degrees.
  • Longitude: (Double) The longitude in degrees.
  • Altitude: (Double?) The altitude in meters above the WGS 84 ellipsoid.
  • Accuracy: (Double) The accuracy of the position in meters.
  • Point: (BasicGeoposition) A basic structure representing the latitude and longitude.
  • Speed: (Double?) The speed in meters per second.
  • Heading: (Double?) The heading in degrees.
  • AltitudeAccuracy: (Double?) The accuracy of the altitude in meters.
  • Timestamp: (DateTime) The time at which the position was determined.

Getting Location

To get the user's current location, you typically follow these steps:

  1. Instantiate a Geolocator object.
  2. Set the DesiredAccuracy. For the most precise location, use PositionAccuracy.High.
  3. Call the GetGeopositionAsync() method. This returns a IAsyncOperation<Geoposition>.
  4. Await the result to get the Geoposition object.
  5. Access the latitude and longitude from Geoposition.Coordinate.

Tip:

Always handle potential exceptions that might occur during location retrieval, such as when location services are disabled or denied.

// C# Example
using Windows.Devices.Geolocation;

async void GetCurrentLocation()
{
    var geolocator = new Geolocator();
    geolocator.DesiredAccuracy = PositionAccuracy.High;

    try
    {
        Geoposition pos = await geolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(30));
        double latitude = pos.Coordinate.Latitude;
        double longitude = pos.Coordinate.Longitude;
        Debug.WriteLine($"Latitude: {latitude}, Longitude: {longitude}");
    }
    catch (Exception ex)
    {
        // Handle exceptions, e.g., location denied or not available
        Debug.WriteLine("Error getting location: " + ex.Message);
    }
}

Access Permissions

Before your application can access location data, the user must grant permission. This is handled through the app's manifest and runtime prompts.

In your application's manifest file (Package.appxmanifest), ensure you have declared the location capability:

<Capabilities>
    <Capability Name="internetClient" />
    <Capability Name="location" />
</Capabilities>

At runtime, when your app first attempts to access location data, Windows will present a dialog asking the user for permission. You can also check the current status of location services using Geolocator.RequestAccessAsync() and Geolocator.LocationStatus.

Note:

Users can manage location permissions in the Windows Settings app. Your app should gracefully handle scenarios where permission is denied or revoked.

Handling Errors and Status Changes

Location services can fail for various reasons. It's crucial to implement robust error handling and respond to status changes.

Common Exceptions:

  • UnauthorizedAccessException: Occurs if the app doesn't have permission to access location.
  • AccessDeniedException: Occurs if location services are turned off by the user or policy.
  • TimeoutException: If GetGeopositionAsync times out.

Handling StatusChanged Event:

You can subscribe to the StatusChanged event of the Geolocator to be notified when the service status changes (e.g., from Ready to Disabled).

// C# Example
geolocator.StatusChanged += Geolocator_StatusChanged;

private void Geolocator_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
{
    switch (args.Status)
    {
        case PositionStatus.Ready:
            // Location service is available
            break;
        case PositionStatus.Disabled:
            // Location service is disabled
            break;
        case PositionStatus.NotAvailable:
            // Location service is not available on this device
            break;
        // ... other statuses
    }
}

Advanced Features

Geofencing:

While not directly part of the core Geolocation namespace, UWP provides Windows.Devices.Geolocation.Geofencing for creating virtual geographic boundaries and triggering actions when the device enters or exits them.

Geocoding and Reverse Geocoding:

For converting between coordinates and addresses, you would typically use the Windows.Devices.Geolocation.Geocoding namespace, which includes classes like Geocoder.

Heading and Speed:

The Geocoordinate object also provides information about the device's Heading (direction of movement) and Speed, if available from the sensors.

Best Practices

  • Request Minimal Accuracy: Only request PositionAccuracy.High if absolutely necessary. Lower accuracy settings consume less power and may be faster.
  • Respect User Privacy: Clearly inform users why you need their location and ask for permission.
  • Handle Permissions Gracefully: Design your UI to guide users through granting permissions and to inform them if location access is denied or unavailable.
  • Use StartListening and StopListening: For continuous tracking, use these methods to manage power consumption. Stop listening when your app is not actively using the location.
  • Check LocationStatus: Before attempting to get location data, check the LocationStatus to ensure the service is ready.
  • Implement Timeouts: Use the optional timeout parameters in GetGeopositionAsync to prevent your app from hanging indefinitely.