1

I'm trying to implement a functionality in my app which allows you to find a place by address using Google Maps Api.
I'm trying to use AsyncTask and JSON to do it, but it always throws org.json.JSONException index 0 out of range (even if the location exists). I used to have the below code without async task, but it throwed exceptions when downloaded from playstore.

private class FindByAddress extends AsyncTask<String, Void, LatLng> {
@Override
public LatLng doInBackground(String... placesName) {
    HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?address=" +placesName+"&ka&sensor=false");
    HttpClient client = new DefaultHttpClient();
    HttpResponse response;
    StringBuilder stringBuilder = new StringBuilder();

    // Building/getting the JSON object...
    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();
    }

    // Collect results
    Double lon = new Double(0);
    Double lat = new Double(0);

    // IT MESSES UP HERE, index out of range [0..0) on getJSONObject
    try {
        lon = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
                .getJSONObject("geometry").getJSONObject("location")
                .getDouble("lng");

        lat = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
                .getJSONObject("geometry").getJSONObject("location")
                .getDouble("lat");

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return new LatLng(lat, lon);

}

@Override
protected void onPostExecute(LatLng latilen) {
    // Show results
    if(latilen.latitude!=0 && latilen.longitude!=0){
        if(idioma.equals("english"))
            Toast.makeText(MainActivity.this, "Location found", Toast.LENGTH_SHORT).show();
        else if(idioma.equals("spanish"))
            Toast.makeText(MainActivity.this, "Dirección encontrada", Toast.LENGTH_SHORT).show();
        googleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(latilen.latitude, latilen.longitude)));
    }
    else if(idioma.equals("english"))
        Toast.makeText(MainActivity.this, "Location not found", Toast.LENGTH_SHORT).show();
    else if(idioma.equals("spanish"))
        Toast.makeText(MainActivity.this, "Dirección no encontrada", Toast.LENGTH_SHORT).show();
    }
}

I read somewhere that this needs to be in an asynctask, otherwise it throws an android.os.networkonmainthreadexception (which was my problem earlier). When I didnt have it in an asynctask at least it worked in my device (but not when downloaded from PlayStore).
With this AsyncTask thing doesn't work in any way.

I used to have this problem, so I had to change all the code for the one shown in the answer from @Ani in that same question.

Thankyou

Community
  • 1
  • 1
Victor
  • 907
  • 2
  • 17
  • 42
  • 1
    Are you supposed to be passing an array of strings with the `address` param in your url? Have you tried putting some debug breakpoints or some log calls to make sure your values are getting set like you think they are? Like are you making sure stringBuilder is appending what you think and jSonObjecct(stringBuilder.toString()) is doing what you think? – zgc7009 Oct 10 '14 at 15:42
  • 1
    Looking at Ani's answer from your link, change ` + placesName + ` to ` + placesName[0] + ` as the parameter for an AsyncTask takes the form of an array. – zgc7009 Oct 10 '14 at 15:44
  • @zgc7009 You got it!!! thats the answer, you can put it and I will mark it as correct. I hadnt done any of those things you said because the code did work when it wasnt in AsyncTask. Thankyou very much for your knowledge – Victor Oct 10 '14 at 15:46
  • See the edit in my answer, glad it helped :) – zgc7009 Oct 10 '14 at 15:51

1 Answers1

1

If I understand what you are trying to do correctly, why don't you just use a GeoCoder...

double lat, lng;
Geocoder coder = new Geocoder(this, Locale.US);
List<Address> results;
try{
    results =  = coder.getLocationFromName(placeName, 5);    // 5 is max number of results
    if(results != null){
        Address location = results.get(0);
        lat = location.getLatitude();
        lng = location.getLongtitude();
    }
}

EDIT

Since you were having a weird bug with the GeoCoding I understand wanting/needing to do an alternate method. You are basically just making and parsing the code yourself (probably how GeoCoding handles it though I haven't looked at the source). Thanks to your link, I was able to notice the culprit.

AsyncTasks doInBackground method parameter takes the form of an array. Because of this you need to change your url call from ... + placesName + ... to ... + placesName[0] + .... Glad I was able to help. Best of luck with your project!

zgc7009
  • 3,371
  • 5
  • 22
  • 34
  • In fact I did have that solution in first place, but I had the same problem: it worked when compiled in my device but not when downloaded from PlayStore. I did some research and found this, http://stackoverflow.com/questions/16119130/android-java-io-ioexception-service-not-available so I changed all the code for the one in the answer "Don't Rebooting the Device use this" from ani in that same question – Victor Oct 10 '14 at 15:37
  • 1
    @Victor As long as you attempted it first, since that is the native way. Sounds like a frustrating bug. Best of luck! – zgc7009 Oct 10 '14 at 15:40