Xamarin Essentials Geolocation
The Geolocation class provides APIs to retrieve the device's current geolocation coordinates.
Open Essentials Solution, if you don't have it just download here.
Before coding the view and backend, we have to configure the services that we're going to use.
This NuGet allows a lot of functions that Xamarin.Forms Map doesn't, you can check the comparative here:
Feature | X.F.Maps | X.F.GoogleMaps |
---|---|---|
Map types | Yes | Yes |
Traffic map | - | Yes |
Map events | - | Yes |
Panning with animation | Yes | Yes |
Panning directly | - | Yes |
Pins | Yes | Yes |
Custom Pins | - | Yes |
Pin drag & drop | - | Yes |
Polygons | - | Yes |
Lines | - | Yes |
Circles | - | Yes |
Custom map tiles | - | Yes |
As you can see above, there's a lot of features that GoogleMaps Control offers, that's why I like to use it.
Go to Visual Studio and right click on the solution -> Manage NuGet packages for solution, in the browser just search: Xamarin.Forms.GoogleMaps and install it.
It'll apeear this screen:
Now we have to Init the Service on platforms, we just have the Android Proyect, so we have to open the MainActivity.cs at Essentials.Android proyect.
After this line of code:
1 |
base.OnCreate(savedInstanceState); |
Add this:
1 |
Xamarin.FormsGoogleMaps.Init(this, savedInstanceState); |
Then we have to get an API Key to use the map.
To use the Google Maps API v2 on Android you must generate an API key and add it to your Android project. Follow the instructions in the Xamarin doc on obtaining a Google Maps API v2 key. After following those instructions, paste the API key in the Properties/AndroidManifest.xml file (view source and find/update the following element):
1 2 3 |
<application ...> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR_API_KEY" /> </application> |
You'll also need to enable appropriate permissions by right-clicking on the Android project and selecting Options > Build > Android Application and ticking the following:
AccessCoarseLocation
AccessFineLocation
AccessLocationExtraCommands
AccessMockLocation
AccessNetworkState
AccessWifiState
Internet
That's it, now we're able to code the view and some backend.
At Essentials > Views folder, create a new ContentPage with the name: GeolocationPage.
After that, copy this code into GeolocationPage.xaml file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="Essentials.Views.GeolocationPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:maps="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps"> <ContentPage.Content> <ScrollView> <Grid> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition Height="50" /> <RowDefinition Height="50" /> <RowDefinition Height="50" /> <RowDefinition Height="300" /> </Grid.RowDefinitions> <Label Grid.Row="0" FontSize="30" HorizontalOptions="Center" Text="Geolocation" TextColor="{StaticResource NavigationPrimary}" VerticalOptions="Center" /> <Button Grid.Row="1" BackgroundColor="LightBlue" Clicked="Button_Clicked" CornerRadius="25" HorizontalOptions="Center" Text="Get My Location" WidthRequest="150" /> <Label x:Name="latitudeLabel" Grid.Row="2" Margin="50,0" TextColor="{StaticResource SecondColor}" /> <Label x:Name="longitudeLabel" Grid.Row="3" Margin="50,0" TextColor="{StaticResource SecondColor}" /> <maps:Map x:Name="myMap1" Grid.Row="4" MapType="Street" /> </Grid> </ScrollView> </ContentPage.Content> </ContentPage> |
Now we have a beautiful view.
At GeolocationPage.xaml.cs copy this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
using System; using Xamarin.Essentials; using Xamarin.Forms; using Xamarin.Forms.GoogleMaps; using Xamarin.Forms.Xaml; namespace Essentials.Views { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class GeolocationPage : ContentPage { public GeolocationPage() { InitializeComponent(); myMap1.Pins.Add(new Pin { Type = PinType.Place, Label = "Pin description Here", Icon = BitmapDescriptorFactory.DefaultMarker(Color.FromHex("#348ABF")), Position = new Position(19.40190034252843, -99.07911525356314), Tag = "This is the tag !!!", IsVisible = true }); myMap1.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(19.40190034252843, -99.07911525356314), Distance.FromMeters(500)), false); } private async void Button_Clicked(object sender, System.EventArgs e) { try { var location = await Geolocation.GetLastKnownLocationAsync(); if (location != null) { latitudeLabel.Text = $"Latitude: {location.Latitude}"; longitudeLabel.Text = $"Longitude: {location.Longitude}"; myMap1.Pins.Clear(); myMap1.Pins.Add(new Pin { Type = PinType.Place, Label = "Pin description Here", Icon = BitmapDescriptorFactory.DefaultMarker(Color.FromHex("#348ABF")), Position = new Position(location.Latitude, location.Longitude), Tag = "This is the tag !!!", IsVisible = true }); myMap1.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(location.Latitude, location.Longitude), Distance.FromMeters(500)), false); } } catch (FeatureNotSupportedException fnsEx) { // Handle not supported on device exception } catch (FeatureNotEnabledException fneEx) { // Handle not enabled on device exception } catch (PermissionException pEx) { // Handle permission exception } catch (Exception ex) { // Unable to get location } } } } |
As you can see in that file at the line number 31, we are implementing a method from Xamarin Essentials that gets our location
Then is stored in location variable, compared if is not null and finally just fill our labels respectively.
One important thing is that when you prees the Get my location button, automatically request the location permission.
That's very cool, but if you want to request it manually, you must have to install another nuget: Plugin.Permissions
The last step as the previously posts, is just add the page in our flyout. Let's do it.
In the AppShell.xaml above this line:
1 2 3 |
<ShellItem Title="Connectivity" FlyoutIcon="{ext:ImageResource Essentials.Resources.Images.FlyoutIcon.png}"> <ShellContent ContentTemplate="{DataTemplate local:ConnectivityPage}" /> </ShellItem> |
Just add this:
1 2 3 |
<ShellItem Title="Geolocation" FlyoutIcon="{ext:ImageResource Essentials.Resources.Images.FlyoutIcon.png}"> <ShellContent ContentTemplate="{DataTemplate local:GeolocationPage}" /> </ShellItem> |
Okay, run the app and again, if you like it, just share with your friends !!! Than you.
Related Links
Xamarin Essentials NuGet Essentials
Xamarin Essentials Documentation Microsoft Xamarin.Essentials Documentation
Xamarin Essentials Geolocation Documentation Geolocation
Xamarin Forms GoogleMaps NuGet Xamarin.Forms.GoogleMaps
Xamarin Forms GoogleMaps Documentation Xamarin.Forms.GoogleMaps Documentation
Xamarin Forms Plugin.Permissions Plugin.Permissions
Completed Solution Essentials Repo