使用AsyncTask和JSON在Google Maps APIv2上按地址获取位置

时间:2014-10-10 15:26:31

标签: android json google-maps android-asynctask google-maps-api-2

我正在尝试在我的应用中实现一项功能,该功能允许您使用Google Maps Api按地址查找地点。我正在尝试使用AsyncTask和JSON来执行此操作,但它总是抛出org.json.JSONException index 0 out of range(即使该位置存在)。我以前的代码没有异步任务,但是从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();
    }
}

我在某处读到这需要在asynctask中,否则会抛出android.os.networkonmainthreadexception(这是我之前的问题)。当我没有把它放在asynctask中时,至少它在我的设备中有效(但是从PlayStore下载时却没有)。
使用这个AsyncTask的东西不起作用。

我以前有this problem,所以我必须在同一个问题中更改@Ani答案中显示的所有代码。

三江源

1 个答案:

答案 0 :(得分:1)

如果我理解你要做的正确,你为什么不只使用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();
    }
}

修改

由于您遇到了GeoCoding的奇怪错误,我理解想要/需要做另一种方法。您基本上只是自己编写和解析代码(可能是GeoCoding如何处理它,尽管我没有查看源代码)。感谢您的链接,我能够注意到罪魁祸首。

AsyncTasks doInBackground方法参数采用数组的形式。因此,您需要将您的网址调用从... + placesName + ...更改为... + placesName[0] + ...。很高兴我能够提供帮助。祝你的项目好运!