Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Helper Class to Get the Current Location on a Windows Phone Just Once

0.00/5 (No votes)
15 Jan 2011 1  
Here is a helper class to get the current location on a Windows Phone just once

Getting the location on Windows Phone is done via the GeoCoordinateWatcher. The coordinate watcher has some best practices associated with it one of which is to minimize power consumption. Once you turn this thing on, it's going to be using the GPS to stream location event back to your app which will hit the battery.

There are some instances where you may note a running notification of the current portion but just want the current position (for instance, you may want to initialize the position on a map but not track changes to position).

So this is a small helper class that starts up the coordinate watcher asynchronously, returns the first coordinate found and then shuts it down. One could use TryStart like so:

using (var watcher =  new 
                GeoCoordinateWatcher(GeoPositionAccuracy.Default))
{
    var location = watcher.TryStart
                (false, TimeSpan.FromMilliseconds(1000));
}

but since that will block your UI thread (assuming you call it from the UI) you'd need to wrap it in some asynchronous stuff anyways.
So I use this class:

public class ImmediateLocation : IDisposable
{
    private GeoCoordinateWatcher _watcher;
    private Action<GeoCoordinate> _action;

    public ImmediateLocation(Action<GeoCoordinate> a)
    {
        Debug.Assert(a != null);

        _action = a;
    }

    public void GetLocation()
    {
        if (_watcher == null)
        {
            _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
            _watcher.MovementThreshold = 1000;

            _watcher.PositionChanged += new 
                EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>
                (_watcher_PositionChanged);
            _watcher.StatusChanged += new 
                EventHandler<GeoPositionStatusChangedEventArgs>
                (_watcher_StatusChanged);

            _watcher.Start(false);

            if (_watcher.Status == GeoPositionStatus.Disabled
                || _watcher.Permission == GeoPositionPermission.Denied)
                Dispose();
        }
    }

    void _watcher_StatusChanged(object sender, 
        GeoPositionStatusChangedEventArgs e)
    {
        if (e.Status == GeoPositionStatus.Disabled 
            || _watcher.Permission == GeoPositionPermission.Denied)
            Dispose();
    }

    void _watcher_PositionChanged(object sender, 
        GeoPositionChangedEventArgs<GeoCoordinate> e)
    {
        _action(e.Position.Location);
        Dispose();
    }

    public void Dispose()
    {
        if (_watcher != null)
        {
            _watcher.Stop();
            _watcher.PositionChanged -= new 
                EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>
                (_watcher_PositionChanged);
            _watcher.StatusChanged -= new 
                EventHandler<GeoPositionStatusChangedEventArgs>
                (_watcher_StatusChanged);
            _watcher.Dispose();
        }
        _watcher = null;
        _action = null;
    }
} 

Then you can just do this:

var immediate = new ImmediateLocation(x => location = x);
immediate.GetLocation();

GeoCoordinate location;

It acts like a one time use, fire and forget location setter that cleans itself up when done. It does have Dispose if you want to manage the lifetime more closely.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here