user1641519
user1641519

Reputation: 387

Xamarin android get address based on latitude and longitude

Im new new to xamarin Android....I have an app which shows users current latitude and longitude which seems to be working...

Now, from latitude and longitude, Im trying to get address using API Geocoder. Im passing proper latitude and longitude but its not giving me any address though I cant see any error.

Following is my code :-

async Task<Address> ReverseGeocodeCurrentLocationAsync(double Latitude, double Longitude)
        {
            Geocoder geocoder = new Geocoder(this);
            IList<Address> addressList = await
                geocoder.GetFromLocationAsync(Latitude, Longitude, 10); // ???????? its not wrking....Here, Im properly able to pass latitude and longitude still issue getting adress. 

            IList<Address> testaddresses = await geocoder.GetFromLocationAsync(42.37419, -71.120639, 1); // ???????? i tried both sync and async method but not wrking....

            Address address = addressList.FirstOrDefault();
            return address;
        }

// calling part Address address = await ReverseGeocodeCurrentLocationAsync(location.Latitude, location.Longitude);

Also, you can find source code at :https://github.com/4pawan/XamarinDroidSample

Please let me know what I'm doing wrong and how to rectify ?

Regards, Pawan

Upvotes: 2

Views: 5766

Answers (2)

HO LI Pin
HO LI Pin

Reputation: 1691

This is how you get the full address using Latitude and Longitude in Xmarin android

using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Xamarin.Essentials;
using System;
using System.Threading.Tasks;
using Android.Content.PM;
using System.Collections.Generic;
using System.Linq;

namespace GeoLocation
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {

        TextView txtnumber;


        protected async override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            txtnumber = FindViewById<TextView>(Resource.Id.textView1);

            double GmapLat = 0;
            double GmapLong = 0;



            try
            {

                var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
                var location = await Geolocation.GetLocationAsync(request);
                txtnumber.Text = "finish get geolocation";
                GmapLat = location.Latitude;
                GmapLat=location.Longitude;

                if (location != null)
                {

                    var placemarks = await Geocoding.GetPlacemarksAsync(location.Latitude, location.Longitude);
                    var placemark = placemarks?.FirstOrDefault();
                    if (placemark != null)
                    {
                        // Combine those string to built full address... placemark.AdminArea ,placemark.CountryCode , placemark.Locality , placemark.SubAdminArea , placemark.SubLocality , placemark.PostalCode
                        string GeoCountryName = placemark.CountryName;

                    }

                    txtnumber.Text = "GPS: Latitude " + location.Latitude + " Longitude " + location.Longitude;
                }
            }
            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
                txtnumber.Text = ex.Message.ToString();
            }



        }



    }



}

Upvotes: 0

SushiHangover
SushiHangover

Reputation: 74209

  • Always check if a Geocoder is available as this requires a background service to be available and it is possible that it is not available as it not included in the base Android framework:

    Geocoder.IsPresent

  • Register your app in Google's Dev API Console

  • Add your Google Map API Key your your app's manifest

  • If you are using Google's fused location provider (via Google Play services) and need Geo-Coding, make sure your app has ACCESS_FINE_LOCATION permission:

  • Network connectivity is required to receive an address list from the Geocoder service.

  • Depending upon your device's Geocoder service, it can take more then one request before "Google" or your device's Geocoder service replies with a list of addresses.

    • Do not spam the service, you will get throttled, use an increasing time delay between requests.

Note: A extremely frequent response is:

`Timed out waiting for response from server`

In this case, wait a short peroid time and retry.

But there are a number of other errors that include, no addresses found, invalid lat/log, geocoder not currently available, etc...

Note: I normally use ReactiveUI to wrap the failures, retries and continuation, but here is a simple example:

Basic Geocode method (much like yours):

async Task<Address> ReverseGeocodeLocationAsync(Location location)
{
    try
    {
        var geocoder = new Geocoder(this);
        IList<Address> addressList = await geocoder.GetFromLocationAsync(location.Latitude, location.Longitude, 3);
        Address address = addressList.FirstOrDefault();
        return address;
    }
    catch (Exception e)
    {
        Log.Error(TAG, e.Message);
    }
    return null;
}

The Retry:

int retry = 0;
Address address = null;
do
{
    address = await ReverseGeocodeLocationAsync(_currentLocation);
    if (address != null)
    {
        Log.Info(TAG, $"Address found: {address.ToString()}");
        // Do something with the address(es)
        break;
    }
    retry++;
    Log.Warn(TAG, $"No addresses returned...., retrying in {retry * 2} secs");
    await Task.Delay(retry * 2000);
} while (retry < 10);

Upvotes: 2

Related Questions