Android
iOS
 

Get Current Device Location

This recipe will show how to get the location of the device. When a button on the activity is clicked by the user, then a street address that is close to the location will also be displayed.

Recipe

  1. Create a new Xamarin.Android application named GetLocation.
  2. Edit AssemblyInfo.cs, and declare the permissions necessary to use the LocationServices:
[assembly: UsesPermission(Manifest.Permission.AccessFineLocation)]
[assembly: UsesPermission(Manifest.Permission.AccessCoarseLocation)]

3. Declare the permissions necessary to use the Geocoder class. This is not strictly necessary for determining, but necessary for the Geocoder class that is also used by this recipe:

[assembly: UsesPermission(Manifest.Permission.Internet)]

4. Edit Main.axml so that it contains two TextViews and a Button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="location"
      android:id="@+id/location_text"
    />
  <Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/get_address_button"
    android:text="Get Address"
    />
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="address"
      android:id="@+id/address_text"
   />
</LinearLayout>

5. Add some instance variables to Activity1.cs:

private Location _currentLocation;
private LocationManager _locationManager;
private TextView _locationText;
private TextView _addressText;

6. Change OnCreate:

base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);

_addressText = FindViewById<TextView>(Resource.Id.address_text);
_locationText = FindViewById<TextView>(Resource.Id.location_text);
FindViewById<TextView>(Resource.Id.get_address_button).Click += AddressButton_OnClick;

InitializeLocationManager();

The handler for button click will be covered below in step 11 below. The logic for initializing the LocationManager is placed in its own method for clarity.

7. Add a method called InitializeLocationManager to Activity1:

private void InitializeLocationManager()
{
    _locationManager = (LocationManager) GetSystemService(LocationService);
    var criteriaForLocationService = new Criteria
                                         {
                                             Accuracy = Accuracy.Fine
                                         };
    var acceptableLocationProviders = _locationManager.GetProviders(criteriaForLocationService, true);

    if (acceptableLocationProviders.Any())
    {
        _locationProvider = acceptableLocationProviders.First();
    }
    else
    {
        _locationProvider = String.Empty;
    }
}

To determine the location of the device, it is necessary to use the LocationManager. The LocationManager is asked for a list of location providers that best match a certain set of criteria.

8. Edit Activity1.cs, and have it implement the interface ILocationListener and add in the methods required by that interface:

[Activity(Label = "Get Location", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity, ILocationListener
{
    // removed code for clarity

    public void OnLocationChanged(Location location) {}

    public void OnProviderDisabled(string provider) {}

    public void OnProviderEnabled(string provider) {}

    public void OnStatusChanged(string provider, Availability status, Bundle extras) {}
}

9. Override OnResume so that Activity1 will begin listening to the LocationManager:

protected override void OnResume()
{
    base.OnResume();
    _locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
}

10. Override OnPause and unsubscribe Activity1 from the LocationManager:

protected override void OnPause()
{
    base.OnPause();
    _locationManager.RemoveUpdates(this);
}

We do this to give the GPS a chance to shut down when our Activity is in the background.

11. Add as method called AddressButton_OnClick to Activity1:

private void AddressButton_OnClick(object sender, EventArgs eventArgs)
{
    if (_currentLocation == null)
    {
        _addressText.Text = "Can't determine the current location.";
        return;
    }

    new Thread(() =>
                   {
                       var addressText = "Unable to find a location.";
                       var geocoder = new Geocoder(this);
                       var addressList = geocoder.GetFromLocation(_currentLocation.Latitude, _currentLocation.Longitude, 50);
                       var address = addressList.FirstOrDefault();

                       if (address != null)
                       {
                           var deviceLocation = new StringBuilder();
                           for (var i = 0; i < address.MaxAddressLineIndex; i++)
                           {
                               deviceLocation.Append(address.GetAddressLine(i))
                                   .AppendLine(",");
                           }
                           _addressText.Text = deviceLocation.ToString();
                       }
                       RunOnUiThread(() => { _addressText.Text = addressText; });
                   }).Start();
}

12. Change the method OnLocationChanged:

public void OnLocationChanged(Location location)
{
    _currentLocation = location;
    if (_currentLocation == null)
    {
        _locationText.Text = "Unable to determine your location.";
    }
    else
    {
        _locationText.Text = String.Format("{0},{1}", _currentLocation.Latitude, _currentLocation.Longitude);
    }
}

13. Run the application. After a short while, the location of the GPS should be displayed:

14. Click the button Get Address, and then the location should be translated into a street address:

Additional Information

The LocationManager provides access to the system location services.