简体   繁体   中英

Get values by key in complex Google Geocoding JSON Object - Java - android

I used this helpful code snippet in order to get the current location in my android application and now I want to get the route (street_address), street_number , postal_code and country (always long_name ) in a Google Geocoding JSON Object. At the moment I use a do - while loop and then split formatted_address to get the desired results, but I think it would be better to access the value by its key.

The JSON looks like this:

{
"results": [
    {
        "types": [
            "street_address"
        ],
        "formatted_address": "RotenturmstraÃe 2, 1010 Vienna, Austria",
        "address_components": [
            {
                "types": [
                    "street_number"
                ],
                "short_name": "2",
                "long_name": "2"
            },
            {
                "types": [
                    "route"
                ],
                "short_name": "Rotenturmstr.",
                "long_name": "RotenturmstraÃe"
            },
            {
                "types": [
                    "sublocality_level_1",
                    "sublocality",
                    "political"
                ],
                "short_name": "Innere Stadt",
                "long_name": "Innere Stadt"
            },
            {
                "types": [
                    "locality",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "administrative_area_level_1",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "country",
                    "political"
                ],
                "short_name": "AT",
                "long_name": "Austria"
            },
            {
                "types": [
                    "postal_code"
                ],
                "short_name": "1010",
                "long_name": "1010"
            }
        ],
        "geometry": {
            "viewport": {
                "southwest": {
                    "lng": 16.3719497197085,
                    "lat": 48.20797491970851
                },
                "northeast": {
                    "lng": 16.3746476802915,
                    "lat": 48.2106728802915
                }
            },
            "location": {
                "lng": 16.3732987,
                "lat": 48.2093239
            },
            "location_type": "ROOFTOP"
        }
    },
    {
        "types": [
            "neighborhood",
            "political"
        ],
        "formatted_address": "Stephansdom, 1010 Vienna, Austria",
        "address_components": [
            {
                "types": [
                    "neighborhood",
                    "political"
                ],
                "short_name": "Stephansdom",
                "long_name": "Stephansdom"
            },
            {
                "types": [
                    "sublocality_level_1",
                    "sublocality",
                    "political"
                ],
                "short_name": "Innere Stadt",
                "long_name": "Innere Stadt"
            },
            {
                "types": [
                    "locality",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "administrative_area_level_1",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "country",
                    "political"
                ],
                "short_name": "AT",
                "long_name": "Austria"
            },
            {
                "types": [
                    "postal_code"
                ],
                "short_name": "1010",
                "long_name": "1010"
            }
        ],
        "geometry": {
            "bounds": {
                "southwest": {
                    "lng": 16.3663459,
                    "lat": 48.2016949
                },
                "northeast": {
                    "lng": 16.382804,
                    "lat": 48.21546559999999
                }
            },
            "viewport": {
                "southwest": {
                    "lng": 16.3663459,
                    "lat": 48.2016949
                },
                "northeast": {
                    "lng": 16.382804,
                    "lat": 48.21546559999999
                }
            },
            "location": {
                "lng": 16.3767451,
                "lat": 48.2083206
            },
            "location_type": "APPROXIMATE"
        }
    },
    {
        "types": [
            "postal_code"
        ],
        "formatted_address": "1010 Vienna, Austria",
        "address_components": [
            {
                "types": [
                    "postal_code"
                ],
                "short_name": "1010",
                "long_name": "1010"
            },
            {
                "types": [
                    "locality",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "administrative_area_level_1",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "country",
                    "political"
                ],
                "short_name": "AT",
                "long_name": "Austria"
            }
        ],
        "geometry": {
            "bounds": {
                "southwest": {
                    "lng": 16.3552218,
                    "lat": 48.1992606
                },
                "northeast": {
                    "lng": 16.3853131,
                    "lat": 48.2185876
                }
            },
            "viewport": {
                "southwest": {
                    "lng": 16.3552218,
                    "lat": 48.1992606
                },
                "northeast": {
                    "lng": 16.3853131,
                    "lat": 48.2185876
                }
            },
            "location": {
                "lng": 16.3677601,
                "lat": 48.2083556
            },
            "location_type": "APPROXIMATE"
        }
    },
    {
        "types": [
            "sublocality_level_1",
            "sublocality",
            "political"
        ],
        "formatted_address": "Innere Stadt, 1010 Vienna, Austria",
        "address_components": [
            {
                "types": [
                    "sublocality_level_1",
                    "sublocality",
                    "political"
                ],
                "short_name": "Innere Stadt",
                "long_name": "Innere Stadt"
            },
            {
                "types": [
                    "locality",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "administrative_area_level_1",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "country",
                    "political"
                ],
                "short_name": "AT",
                "long_name": "Austria"
            },
            {
                "types": [
                    "postal_code"
                ],
                "short_name": "1010",
                "long_name": "1010"
            }
        ],
        "geometry": {
            "bounds": {
                "southwest": {
                    "lng": 16.3552218,
                    "lat": 48.1992606
                },
                "northeast": {
                    "lng": 16.3853131,
                    "lat": 48.2185876
                }
            },
            "viewport": {
                "southwest": {
                    "lng": 16.3552218,
                    "lat": 48.1992606
                },
                "northeast": {
                    "lng": 16.3853131,
                    "lat": 48.2185876
                }
            },
            "location": {
                "lng": 16.3697428,
                "lat": 48.2088774
            },
            "location_type": "APPROXIMATE"
        }
    },
    {
        "types": [
            "administrative_area_level_1",
            "political"
        ],
        "formatted_address": "Vienna, Austria",
        "address_components": [
            {
                "types": [
                    "administrative_area_level_1",
                    "political"
                ],
                "short_name": "Vienna",
                "long_name": "Vienna"
            },
            {
                "types": [
                    "country",
                    "political"
                ],
                "short_name": "AT",
                "long_name": "Austria"
            }
        ],
        "geometry": {
            "bounds": {
                "southwest": {
                    "lng": 16.1826199,
                    "lat": 48.1182699
                },
                "northeast": {
                    "lng": 16.5774999,
                    "lat": 48.3230999
                }
            },
            "viewport": {
                "southwest": {
                    "lng": 16.1826199,
                    "lat": 48.1182699
                },
                "northeast": {
                    "lng": 16.5774999,
                    "lat": 48.3230999
                }
            },
            "location": {
                "lng": 16.3738138,
                "lat": 48.20823499999999
            },
            "location_type": "APPROXIMATE"
        }
    }
]

Here is my code:

public static JSONObject getLocationInfo(double lat, double lng) {

    HttpGet httpGet = new HttpGet("http://maps.googleapis.com/maps/api/geocode/json?latlng="+ lat+","+lng +"&sensor=true");
    HttpClient client = new DefaultHttpClient();
    HttpResponse response;
    StringBuilder stringBuilder = new StringBuilder();

    try {
        response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream stream = entity.getContent();
        int b;
        while ((b = stream.read()) != -1) {
            stringBuilder.append((char) b);
        }
    } catch (ClientProtocolException e) {
    } catch (IOException e) {
    }

    JSONObject jsonObject = new JSONObject();
    try {
        jsonObject = new JSONObject(stringBuilder.toString());
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return jsonObject;
}

public static String getCurrentLocationViaJSON(double lat, double lng) {

    JSONObject jsonObj = getLocationInfo(lat, lng);
    Log.i("JSON string =>", jsonObj.toString());

    String currentLocation = "testing";
    String street_address = null;
    String postal_code = null; 

    try {
        String status = jsonObj.getString("status").toString();
        Log.i("status", status);

        if(status.equalsIgnoreCase("OK")){
            JSONArray results = jsonObj.getJSONArray("results");
            int i = 0;
            Log.i("i", i+ "," + results.length() ); //TODO delete this
            do{

                JSONObject r = results.getJSONObject(i);
                JSONArray typesArray = r.getJSONArray("types");
                String types = typesArray.getString(0);

                if(types.equalsIgnoreCase("street_address")){
                    street_address = r.getString("formatted_address").split(",")[0];
                    Log.i("street_address", street_address);
                }else if(types.equalsIgnoreCase("postal_code")){
                    postal_code = r.getString("formatted_address");
                    Log.i("postal_code", postal_code);
                }

                if(street_address!=null && postal_code!=null){
                    currentLocation = street_address + "," + postal_code;
                    Log.i("Current Location =>", currentLocation); //Delete this
                    i = results.length();
                }

                i++;
            }while(i<results.length());

            Log.i("JSON Geo Locatoin =>", currentLocation);
            return currentLocation;
        }

    } catch (JSONException e) {
        Log.e("testing","Failed to load JSON");
        e.printStackTrace();
    }
    return null;
}

Any help would be greatly appreciated.

Well in that code example, they use JSONObject, so you're going to want to use getJSONObject(i) , getJSONArray() , and getString() to parse out your data.

It's probably advisable to use a function like that to parse out the data into more readable variables. Otherwise if you're directly using they key, you're going to get things like String street_address = jsonObj.getJSONArray("results").getJSONObject(i).getString("formatted_address") , which is fine, but it's huge.

Also, it's a little unclear what you mean by "it would be better to access the value by its key". In your loop you are accessing the value by its key. The code r.getString("formatted_address") uses the key formatted_address to access the data for that key value pair.

Here's one possible solution:

public JSONObject getCurrentLocationViaJSON(double lat, double lng) {
// Returns a JSONObject with route (street_address), street_number, postal_code and country

    JSONObject jsonObj = getLocationInfo(lat, lng);
    Log.i("JSON string =>", jsonObj.toString());

    String currentLocation = "testing";
    String route = null;
    String street_number = null;
    String postal_code = null; 
    String country = null;

    try {
        String status = jsonObj.getString("status").toString();
        Log.i("status", status);

        if(status.equalsIgnoreCase("OK")){
            JSONArray results = jsonObj.getJSONArray("results");
            int i = 0;
            Log.i("i", i+ "," + results.length() ); //TODO delete this
            do{

                JSONObject r = results.getJSONObject(0);
                JSONArray addressComponentsArray = r.getJSONArray("address_components");
                JSONArray addressComponents = addressComponentsArray.getJSONObject(i);
                JSONArray typesArray = addressComponents.getJSONArray(0);
                String types = typesArray.getString(0);

                if(types.equalsIgnoreCase("street_number")){
                    street_number = addressComponents.getString("short_name");
                    Log.i("street_number", street_number);
                }else if(types.equalsIgnoreCase("postal_code")){
                    postal_code = addressComponents.getString("long_name");
                    Log.i("postal_code", postal_code);
                }else if(types.equalsIgnoreCase("country")){
                    country = addressComponents.getString("long_name");
                    Log.i("country", country);
                }else if(types.equalsIgnoreCase("route")){
                    route = addressComponents.getString("long_name");
                    Log.i("postal_code", postal_code);
                }

                i++;
            }while(i<results.length());

            Log.i("JSON Geo Locatoin =>", currentLocation);
            return currentLocation;
        }

    } catch (JSONException e) {
        Log.e("testing","Failed to load JSON");
        e.printStackTrace();
    }

    JSONObject json = new JSONObject(); 
    json.put("street_number", street_number); 
    json.put("postal_code", postal_code); 
    json.put("country ", country); 
    json.put("route", route); 

    return json;
}

The above method will parse out route (street_address), street_number, postal_code and country (always long_name), store it in a JSONObject, and then return that object. You can access the values with something like:

JSONObject addressDetails = getCurrentLocationViaJSON(100.1, 100.1);
String streetNum = addressDetails.getString("street_number");

This code will provide you address always. Verifed!

public class GeocodeLoader extends AsyncTask<Void, Void, String> {
private WeakReference<TextView> textView;
private WeakReference<ProgressBar> progressBar;
private WeakReference<LatLng> latLng;
private static WeakReference<Context> context;
private String urlString;

public GeocodeLoader ( Context context, LatLng latLng, TextView textView, ProgressBar progressBar) {
    GeocodeLoader.context = new WeakReference<>(context);
    this.textView = new WeakReference<>(textView);
    this.progressBar = new WeakReference<>(progressBar);
    progressBar.setVisibility ( View.VISIBLE );
    this.latLng = new WeakReference<>(latLng);
    this.urlString = createGeocodeURL ();
}

private String createGeocodeURL ( ) {
    String lat = Double.toString ( latLng.get ().latitude );
    String lng = Double.toString ( latLng.get ().longitude );
    return "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "," + lng +
            "&key=" + context.get ().getString ( R.string.google_maps_key );
}

@Override
protected String doInBackground ( Void... params ) {
        String result = "";
        try {
            URL url = new URL ( urlString );
            HttpURLConnection httpsURLConnection = (HttpURLConnection) url.openConnection ();
            httpsURLConnection.setReadTimeout ( 10000 );
            httpsURLConnection.setConnectTimeout ( 15000 );
            httpsURLConnection.setDoInput ( true );
            httpsURLConnection.setRequestMethod ( "GET" );
            httpsURLConnection.connect ();
            int mStatus = httpsURLConnection.getResponseCode ();
            if (mStatus == 200)
                return readResponse ( httpsURLConnection.getInputStream () );
            return result;
        } catch (Exception e) {
            e.printStackTrace ();
        }
        return null;
}

@Override
protected void onPostExecute ( String result ) {
    super.onPostExecute ( result );
    progressBar.get ().setVisibility ( View.GONE );
    textView.get ().setText ( result );
    progressBar.get ().setVisibility ( View.GONE );
}

private static String readResponse ( InputStream inputStream ) throws IOException, JSONException {
    BufferedReader r = new BufferedReader ( new InputStreamReader ( inputStream ) );
    StringBuilder stringBuilder = new StringBuilder ();
    String line;
    while ((line = r.readLine ()) != null) {
        stringBuilder.append ( line );
    }
    JSONObject jsonObject = new JSONObject(stringBuilder.toString());
    return getAddress(jsonObject);
}

private static String getAddress ( JSONObject jsonObject ) {
    String street_address = context.get ().getString (R.string.could_not_retrieve_location );
    try {
        String status = jsonObject.getString("status");
        if(status.equalsIgnoreCase("OK")){
            JSONArray results = jsonObject.getJSONArray("results");
            int i = 0;
            do{
                JSONObject r = results.getJSONObject(i);
                if(!r.getString("formatted_address").equalsIgnoreCase ( "" )){
                    street_address = r.getString("formatted_address");
                    break;
                }
               i++;
            }while(i<results.length());
            return street_address;
        }
    } catch (JSONException ignored) {
    }
    return street_address;
}
}

This method can be called using the below code from any part of your project

new GeocodeLoader ( context, latLng, textView, progressBar ).execute (  );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM