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.

Google Maps NuGet

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

Results



Share this post