This last part in the series will show a different kind of sensor – the Geolocation sensor. In the strict sense, we can’t call this as a sensor, because the geolocation service will get the current location from the GPS sensor if it exists. If not, it will use other methods, like the network of wifi to detect the current location.
To get the current location, you must work in a different way that we worked for the other sensors:
- You must add the Location capability to the app manifest
- The user must consent with the use of the current location
- You should instantiate a new Geolocator instance (and not get one with GetDefault)
- There is no ReadingChanged event, but StatusChanged event
Even with these changes, you will see that it’s very easy to work with the geolocation. In this post we will develop a program that gets the current location and queries a weather service to get the forecast and see if it will rain.
Will it rain?
In Visual Studio, create a blank UWP project. To query the weather, we will use an open source project that has a C# API to query the OpenWeather map (http://openweathermap.org/API), located in https://github.com/joancaron/OpenWeatherMap-Api-Net. We can add this lib by using the Nuget Package manager (right click the References node in Solution Explorer and select Manage Nuget Packages). Just search for openweather and install the lib:
Just one note here: the official package doesn’t support Windows 10, so you must choose a fork of the project (the third project in the list) to install.
Then, you must add the Location capability to the app manifest. On the solution Explorer, open package.appxmanifest and go to the tab Capabilities. There, check the Location box.
Then, in the Main window, add this XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="RainText"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="30"/>
</Grid>
In the constructor of MainPage, we must ask for the user permissions an process the response:
public MainPage()
{
this.InitializeComponent();
InitializeLocator();
}
public enum RainStatus
{
Rain,
Sun
};
private async void InitializeLocator()
{
var userPermission = await Geolocator.RequestAccessAsync();
switch (userPermission)
{
case GeolocationAccessStatus.Allowed:
RainText.Text = "Updating rain status...";
Geolocator geolocator = new Geolocator();
Geoposition pos = await geolocator.GetGeopositionAsync();
try
{
RainText.Text = await GetRainStatus(pos) == RainStatus.Rain ?
"It's possible to rain, you'd better take an umbrella" :
"It will be a bright an shiny day, go out and enjoy";
}
catch
{
RainText.Text = "Got an error while getting weather";
}
break;
case GeolocationAccessStatus.Denied:
RainText.Text = "I cannot check the weather if you don't give me the access to your location...";
break;
case GeolocationAccessStatus.Unspecified:
RainText.Text = "I got an error while getting location permission. Please try again...";
break;
}
}
If the user allows access to the location data, we get the current position with GetGeopositionAsync and then we use this position to get the rain status, using the open weather map API. The GetRainStatus method is:
private async Task GetRainStatus(Geoposition pos)
{
var client = new OpenWeatherMapClient("YourPrivateId");
var weather = await client.CurrentWeather.GetByCoordinates(new Coordinates()
{
Latitude = pos.Coordinate.Point.Position.Latitude,
Longitude = pos.Coordinate.Point.Position.Longitude
});
return weather.Precipitation.Mode == "no" ? RainStatus.Sun : RainStatus.Rain;
}
To use the OpenWeather API, you must register with the site and get an API key. For low usage, the key and usage is free. You can register at http://openweathermap.org/appid
When you run the program, you are able to know if you will need to take an umbrella to go out:
Conclusions
As you could see, working with sensors is very easy and it can offer a better experience for your users. You can integrate them with your apps in many different ways. In this post, I’ve shown how to use the weather API to query if it will rain in your location, a simple, but useful program.
All source code for this project is in https://github.com/bsonnino/GeoLocation
Is there a way to force C# API to fetch the Location coordinates through GPS rather than other sources ?
AFAIK, you cannot force the source to be only the GPS, but you can set the desired accuracy to HIGH and get the source from the GeoPosition that you get and discard the ones that don’t come from the GPS