Service not available in geoCoder

后端 未结 3 1108
再見小時候
再見小時候 2020-12-04 20:15

I am able to get longitude and latitude but getting address i got an error.

public boolean onTouchEvent(MotionEvent event, MapView mapView)

{



        
3条回答
  •  生来不讨喜
    2020-12-04 21:08

    Here is my way to get the address even if Geocoder failed... but first let me explain my own experience with Geocoder:

    For some unknown reason, Geocoder works fine then, suddenly break!.

    What I observed is that, after a while (can be days), Geocoder start to throw "Service not available" exception.

    EDIT-> As mentioned by Christian, the exception is thrown even is isPresent() returns true.<-EDIT END

    Really weird since it was working fine before and no configuration changed occurred:

    • same device
    • same Android version
    • same app
    • same manifest
    • WIFI up and running, Device location feature enabled in settings

    Of course, something changed, but, for the time being, we don't know exactly what. There is a bug opened about that: Issue 38009: 4.1.1 Geocoder throwing exception: IOException: Service not Available

    Last post on this thread (ATTOW) "Probably it's periodically reproducible in android 4.0.x + target API x"

    As a workaround, you can use Google Map

    Here is my GeocoderHelper class that provides a 'Google Map' B Plan in case Geocoder start to fails. In my case, I am just interested in CityName, but you can basically get any data availalbe in google map JSON output

    Usage:

    new GeocoderHelper().fetchCityName(context, location); Then do somthing in onPostExecute() of example code (send broadcast, invoke listener method, set a textView text, whatever)

    GeocoderHelper Class:

    package com..location;
    
    import java.util.List;
    import java.util.Locale;
    
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.BasicResponseHandler;
    import org.json.JSONArray;
    import org.json.JSONObject;
    
    import android.content.Context;
    import android.location.Address;
    import android.location.Geocoder;
    import android.location.Location;
    import android.net.http.AndroidHttpClient;
    import android.os.AsyncTask;
    import android.util.Log;
    
    public class GeocoderHelper
    {
        private static final AndroidHttpClient ANDROID_HTTP_CLIENT = AndroidHttpClient.newInstance(GeocoderHelper.class.getName());
    
        private boolean running = false;
    
        public void fetchCityName(final Context contex, final Location location)
        {
            if (running)
                return;
    
            new AsyncTask()
            {
                protected void onPreExecute()
                {
                    running = true;
                };
    
                @Override
                protected String doInBackground(Void... params)
                {
                    String cityName = null;
    
                    if (Geocoder.isPresent())
                    {
                        try
                        {
                            Geocoder geocoder = new Geocoder(contex, Locale.getDefault());
                            List
    addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1); if (addresses.size() > 0) { cityName = addresses.get(0).getLocality(); } } catch (Exception ignored) { // after a while, Geocoder start to trhow "Service not availalbe" exception. really weird since it was working before (same device, same Android version etc.. } } if (cityName != null) // i.e., Geocoder succeed { return cityName; } else // i.e., Geocoder failed { return fetchCityNameUsingGoogleMap(); } } // Geocoder failed :-( // Our B Plan : Google Map private String fetchCityNameUsingGoogleMap() { String googleMapUrl = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + location.getLatitude() + "," + location.getLongitude() + "&sensor=false&language=fr"; try { JSONObject googleMapResponse = new JSONObject(ANDROID_HTTP_CLIENT.execute(new HttpGet(googleMapUrl), new BasicResponseHandler())); // many nested loops.. not great -> use expression instead // loop among all results JSONArray results = (JSONArray) googleMapResponse.get("results"); for (int i = 0; i < results.length(); i++) { // loop among all addresses within this result JSONObject result = results.getJSONObject(i); if (result.has("address_components")) { JSONArray addressComponents = result.getJSONArray("address_components"); // loop among all address component to find a 'locality' or 'sublocality' for (int j = 0; j < addressComponents.length(); j++) { JSONObject addressComponent = addressComponents.getJSONObject(j); if (result.has("types")) { JSONArray types = addressComponent.getJSONArray("types"); // search for locality and sublocality String cityName = null; for (int k = 0; k < types.length(); k++) { if ("locality".equals(types.getString(k)) && cityName == null) { if (addressComponent.has("long_name")) { cityName = addressComponent.getString("long_name"); } else if (addressComponent.has("short_name")) { cityName = addressComponent.getString("short_name"); } } if ("sublocality".equals(types.getString(k))) { if (addressComponent.has("long_name")) { cityName = addressComponent.getString("long_name"); } else if (addressComponent.has("short_name")) { cityName = addressComponent.getString("short_name"); } } } if (cityName != null) { return cityName; } } } } } } catch (Exception ignored) { ignored.printStackTrace(); } return null; } protected void onPostExecute(String cityName) { running = false; if (cityName != null) { // Do something with cityName Log.i("GeocoderHelper", cityName); } }; }.execute(); } }

    Hope this will help.

提交回复
热议问题