1

I am trying to pass geocoder values from MapFragment to LocationDetailsActivity.

I get the correct values for lat and lng, but when I try to display any of the other values, most of the times I get null values instead of the city and zip (but not always), while a lot of the times I get the correct country and state (also not always).

MapFragment Code:

// Set default latitude and longitude
double latitude = 15.4825766;
double longitude = -5.0076589;

// Get latitude and longitude of the current location and a LatLng object
if (myLocation != null) {
    latitude = myLocation.getLatitude();
    longitude = myLocation.getLongitude();
}

mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {

    @Override
    public void onMapLongClick(LatLng arg0) {

        Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
        try {
                List<Address> allAddresses = geocoder.getFromLocation(arg0.latitude, arg0.longitude, 1);
                if (allAddresses.size() > 0 && allAddresses != null) {
                    Address address = allAddresses.get(0);
                    Intent intent = new Intent(getActivity(), LocationDetailsActivity.class);
                    intent.putExtra("latitude", arg0.latitude);
                    intent.putExtra("longitude", arg0.longitude);
                    intent.putExtra("city", allAddresses.get(0).getLocality());
                    intent.putExtra("zip", allAddresses.get(0).getPostalCode());
                    intent.putExtra("state", allAddresses.get(0).getAdminArea());
                    intent.putExtra("country", allAddresses.get(0).getCountryName());
                    startActivity(intent);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        }
    });

LocationDetailsActivity Code:

    Bundle bundle = getIntent().getExtras();
    double lat = bundle.getDouble("latitude");
    double lng = bundle.getDouble("longitude");
    String city = intent.getStringExtra("city");
    String zip = intent.getStringExtra("zip");
    String state = intent.getStringExtra("state");
    String country = intent.getStringExtra("country");

    // I display my values here
    mFirstValueDisplay.setText(String.valueOf(city));
    mSecondValueDisplay.setText(String.valueOf(zip));
Banana
  • 2,435
  • 7
  • 34
  • 60
  • 1
    I answered a similar question here: http://stackoverflow.com/questions/19059894/google-geocoder-service-is-unavaliable-coordinates-to-address. I believe that this library: https://github.com/mcharmas/Android-ReactiveLocation has a built-in http fallback by now, at least I saw a PR not too long ago on the subject. – cYrixmorten Jul 17 '16 at 10:58

2 Answers2

2

Android's geocoding api is pretty unreliable up-to my experience, I usually make a request to the Google's geocoding webservices on Url : "https://maps.googleapis.com/maps/api/geocode" (If you are familiar with retrofit)

@GET("/json")
    void reverseGeoCode(@Query("latlng") String latlng, @Query("language") String language,
                        @Query("key") String key, Callback<ReverseGeoCode> callback);

latlng The latitude and longitude you want to reverse geocode.

language language of the geocoded response

key Your Api key

Go here for more info

insomniac
  • 11,146
  • 6
  • 44
  • 55
  • A few minutes ago I got all the values correct, so I guess it is not really reliable. I am a beginner coder, so retrofit is not something I am familiar with :) I'm gonna try this approach and hopefully I will make it work. Thanks for the quick reply :) – Banana Jul 17 '16 at 11:01
  • 1
    Even if you are not familiar with retrofit you can still use asynctask to make requests to this webservice – insomniac Jul 17 '16 at 11:02
  • I tried your approach and it worked better so far, but with certain areas still displaying null values. – Banana Jul 17 '16 at 14:23
  • @insomania, how are the results with web api ?. how much is the accuracy of not getting null value. I am facing same problem. Suggest what to use , android api or web service ? – SimpleCoder Jul 31 '17 at 13:21
  • Where do you get ReverseGeoCode from? – powder366 Aug 01 '17 at 11:59
  • @SimpleCoder It has been some time since I have used the GeoCoder API in android, The web API is exactly same as the Platform provided API and it works better also – insomniac Aug 01 '17 at 12:41
  • @powder366 It is an interface method used when you have RetroFit library, If you are not familiar you can refer Kemo's answer – insomniac Aug 01 '17 at 12:43
  • Can you provide me the code of this interface or class, link? – powder366 Aug 01 '17 at 13:07
1

Geocoder often got the values right, but more often than not I got null values. Based on @insomniac's advice I modified my code:

    public void onMapLongClick(final LatLng arg0) {

            RequestQueue queue = Volley.newRequestQueue(getActivity());
            String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + String.valueOf(arg0.latitude) + "," + String.valueOf(arg0.longitude) + "&key=myKeyCode";

            // Request a string response from the provided URL.
            StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            try {
                                JSONArray jObj = new JSONObject(response).getJSONArray("results").getJSONObject(0).getJSONArray("address_components");

                                Intent intent = new Intent(getActivity(), LocationDetailsActivity .class);

                                for (int i = 0; i < jObj.length(); i++) {
                                    String componentName = new JSONObject(jObj.getString(i)).getJSONArray("types").getString(0);
                                    if (componentName.equals("postal_code") || componentName.equals("locality")) {
                                        intent.putExtra(componentName, new JSONObject(jObj.getString(i)).getString("short_name"));
                                    }
                                }

                                intent.putExtra("latitude", arg0.latitude);
                                intent.putExtra("longitude", arg0.longitude);

                                startActivity(intent);

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    int x = 1;
                }
            });
    // Add the request to the RequestQueue.
            queue.add(stringRequest);

It still displays some areas as null. But those are smaller areas. Hope someone finds it helpful.

Banana
  • 2,435
  • 7
  • 34
  • 60
  • if I only want to get city name then which key should I access in if condition?? – Umair Mar 21 '18 at 14:38
  • @Johonsmuthio `locality` should get you the city name for the most cases. At the time I was working on this issue there were cases that cities were not recognized. It was a known bug. – Banana Mar 21 '18 at 18:31
  • what should I write at the place of mykeycode in string url at this place "&key=myKeyCode"? should i write my googlemapsAPI key here ? – Umair Mar 21 '18 at 21:04
  • @Johonsmuthio Yes, that is it. – Banana Mar 22 '18 at 08:08