Obtaining and using location data
[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]
Finding your user's location, and plotting their position on a map.
When developing iOS apps you have probably used the CoreLocation framework to determine your location, and then MapKit to display that position on a map. With Windows 8.1 and Windows Phone 8.1, you can use the Geolocation class to obtain locations, and Bing Maps to provide the mapping data. (Incidentally, Bing Maps can provide other data, including traffic updates and directions.)
Obtaining a location in C#
The C# code to obtain a location is short and sweet, but notice the use of the async keyword. When async is specified, the method acts in a similar way to an Objective-C block, and keeps the code following it from being executed (without blocking the main thread) until the await method returns: in this case, it returns with a Geoposition object. See Quickstart: Calling asynchronous APIs in C# or Visual Basic for more information.
// Add these:
// using Windows.Devices.Geolocation;
// using System.Threading.Tasks;
// using System.Diagnostics;
Geolocator geo = null;
// Notice the use of async
private async void FindLocation()
{
if (geo == null)
{
geo = new Geolocator();
}
try
{
Geoposition pos = await geo.GetGeopositionAsync();
Debug.WriteLine("Latitude: " + pos.Coordinate.Latitude.ToString() + " Longitude: " + pos.Coordinate.Longitude.ToString() + " Accuracy: " + pos.Coordinate.Accuracy.ToString());
}
catch (System.UnauthorizedAccessException)
{
// Failed - location capability not set in manifest, or user blocked location access at run-time.
}
catch (TaskCanceledException)
{
// Cancelled or timed-out.
}
}
Obtaining a location in JavaScript
The JavaScript is very similar to the C# code. It's important to deal with potential errors and failures, in case the user has elected not to allow location data to be used, or if location data cannot be obtained.
var loc = null;
function FindLocation() {
if (loc == null) {
loc = new Windows.Devices.Geolocation.Geolocator();
}
if (loc != null) {
loc.getGeopositionAsync().then(getPositionHandler, errorHandler);
}
}
function getPositionHandler(pos) {
console.log("Latitude: " + pos.coordinate.latitude + " Longitude: " + pos.coordinate.longitude + " Accuracy: " + pos.coordinate.accuracy );
}
function errorHandler(e) {
console.log("Error = " + e.message);
}
An alternative technique for obtaining location data is available to JavaScript developers: the web browser-style navigator.geolocation approach, as detailed is this blog posting: Comparing HTML5 and WinRT Geolocation APIs.
Obtaining a location in C++
Once again, the C++ code required to find the current location is short. As the method runs asynchronously, you must include C++ support for threading by including ppltask.h and the concurrency namespace. SeeConcurrency Runtime for more info.
// Add the following:
#include <ppltasks.h>
using namespace Windows::Devices::Geolocation;
using namespace concurrency;
Geolocator ^geo ;
concurrency::cancellation_token_source geopositionTaskTokenSource;
void WinLog(const wchar_t *text, int n)
// Helper function to display debugging information to output console
{
wchar_t buf[1024];
_snwprintf_s(buf, 1024, _TRUNCATE, L"%s %d\n", text, n);
OutputDebugString(buf);
}
void MainPage::FindLocation()
{
geo = ref new Geolocator();
task<Geoposition^> geopositionTask(geo->GetGeopositionAsync(), geopositionTaskTokenSource.get_token());
geopositionTask.then([this](task<Geoposition^> getPosTask)
{
try
{
Geoposition^ pos = getPosTask.get();
WinLog(L"Latitude",pos->Coordinate->Latitude);
WinLog(L"Longitude",pos->Coordinate->Longitude);
WinLog(L"Accuracy",pos->Coordinate->Accuracy);
}
catch (AccessDeniedException^)
{
//
}
catch (task_canceled&)
{
// Cancelled or timed-out
}
});
}
Plotting a location
The recommended approach to displaying location data on a map is to use Bing Maps. As discussed in the topic Getting Started with Bing Maps, there are several ways to access this mapping data, including using a non-API web-based solution and a dedicated Windows 8 control. The simpler web solution can display a custom map, but it lacks interactivity, includes various other on-screen controls and doesn't provide a seamless app experience. It is worth the extra effort to make use of the custom control.
Accessing the dedicated Bing Maps control, or using the more advanced features of the Bing Maps service, requires you to register for a special key to identify both you and your app. See Getting a Bing Maps Key for more details. Once you have the key, using the control is straightforward, as explained in this topic: How to display your location using Bing Maps (Windows Store apps using C#/VB/C++ and XAML) which contains a helpful video.
On a related note, your Windows Store app can launch the built-in Maps app by following the URI scheme, which allows, among other things, opening the app centered on a specific location. See URI Scheme for maps application for more info.
Things to remember
- You must configure your app to support location in the manifest file or it will throw an exception. Open Package.appxmanifest, select the Capabilities tab and check Location.
- The user can chose to opt-out of providing location data, and your app must respond gracefully if they do (see exception handlers and error handlers in the sample code).
- Don't request location data until you actually need it, and don't do it more often than is necessary.
- Location data is personal information, and so you must take care what you do with it. See this topic on privacy for guidance.
Related topics
Obtaining location
Guidelines for location-aware apps (Windows Store apps using JavaScript and HTML)
Detecting geolocation (Windows Store apps using JavaScript and HTML)
Quickstart: detecting a user's location (Windows Store apps using C#/VB/C++ and XAML)
Geolocator.GetGeopositionAsync() | getGeopositionAsync() method
Plotting location
How to display your location using Bing Maps (Windows Store apps using C#/VB/C++ and XAML)