谷歌地图在Android中通过HTTPS反向地理编码

谷歌地图在Android中通过HTTPS反向地理编码,android,google-maps,https,google-maps-android-api-2,Android,Google Maps,Https,Google Maps Android Api 2,我正在制作谷歌地图应用程序。由于Geocoder类返回空(超出[0]的范围),我目前正在尝试HTTPS Google maps反向地理编码。 这是我的onClick调用: public JSONArray getAddress(LatLng latLng) throws IOException { URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?latlng="+latLng.latitude+

我正在制作谷歌地图应用程序。由于Geocoder类返回空(超出[0]的范围),我目前正在尝试HTTPS Google maps反向地理编码。 这是我的onClick调用:

  public JSONArray getAddress(LatLng latLng) throws IOException {
    URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?latlng="+latLng.latitude+","+latLng.longitude+"&key=AIza***********************");
    Async async =new Async();
    async.execute(url);
    JSONArray response = async.jsonArray;

    return response;
}
这是异步子类:

public class Async extends AsyncTask<URL, Void, JSONArray> {
    public JSONArray jsonArray;
    @Override
    protected JSONArray doInBackground(URL... params) {
        BufferedReader reader;
        InputStream is;

        try {

            StringBuilder responseBuilder = new StringBuilder();
            HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.connect();
            is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is));
            for (String line; (line = reader.readLine()) != null; ) {
                responseBuilder.append(line).append("\n");
            }
            jsonArray = new JSONArray(responseBuilder.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jsonArray;
    }
4天来,我一直在尝试获得与NullPointerException不同的东西。知道我做错了什么吗?在调试模式下连接的平板电脑上测试。
任何帮助都是有用的。我非常绝望

因为AsyncTask是Activity的子类,所以您只需要将LatLng分配给Activity的成员变量,这样就可以在AsyncTask中访问它

然后,在onPostExecute()中添加标记

首先是对活动代码的更改。 除了JSONArray之外,还创建LatLng成员变量:

public class MyMapActivity extends AppCompatActivity implements OnMapReadyCallback
{

    JSONArray js;
    LatLng currLatLng;
    //...............
然后,修改onmaplick以将LatLng分配给实例变量:

@Override
public void onMapClick(LatLng latLng) {
    JSONArray js=null;
    try {

         //assign to member variable:
         currLatLng = latLng;

         //don't use the return value:
         getAddress(latLng);

         //remove this:
         //mMap.addMarker(new MarkerOptions().position(latLng).title(js.getString(0)).draggable(true));//NullPointer
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException p) {
        //todo

    }
然后,在得到响应后,使用onPostExecute放置标记。 另一个主要问题是JSON响应是一个JSONObject,其中包含一个JSONArray。 修正代码如下:

public class Async extends AsyncTask<URL, Void, JSONArray> {
    public JSONArray jsonArray;

    @Override
    protected JSONArray doInBackground(URL... params) {
        BufferedReader reader;
        InputStream is;
        try {

            StringBuilder responseBuilder = new StringBuilder();
            HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.connect();
            is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is));
            for (String line; (line = reader.readLine()) != null; ) {
                responseBuilder.append(line).append("\n");
            }
            JSONObject jObj= new JSONObject(responseBuilder.toString());
            jsonArray = jObj.getJSONArray("results");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jsonArray;
    }


    @Override
    protected void onPostExecute(JSONArray jsonArrayResponse) {
        js = jsonArrayResponse;
        try {
            if (js != null) {
              JSONObject jsFirstAddress = js.getJSONObject(0);
              mMap.addMarker(new MarkerOptions().position(currLatLng).title(jsFirstAddress.getString("formatted_address")).draggable(true));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

在使用JSONArray之前,需要等待AsyncTask完成。AsyncTask是活动的子类吗?另外,您在哪里使用
js
?是的。如何等待?标记标题中的js。我知道这不是解析的方法,但在[0]中获得值后,我将使用onPostExecute方法修复它。显示当前使用
js
.mMap.addMarker(新的MarkerOptions().position(latLng).title(js.getString(0)).draggable(true))的位置;将代码复制到PostExecute?仍然会得到一个空指针,这一次在onPostExecute上的marker:title(js.getString(0))中,它在哪里now@fixxxera我刚刚运行了代码,并意识到响应是一个包含JSONArray的JSONObject,这就是为什么当您尝试创建一个带有结果的JSONArray时它是空的。用修改后的AsyncTask查看更新后的答案。谢谢你!我已经走到一半了(Api密钥不是我需要的,我尝试了JsonObj,它给了我无效IP密钥的IP错误),但你还是救了我一天!非常感谢。
@Override
public void onMapClick(LatLng latLng) {
    JSONArray js=null;
    try {

         //assign to member variable:
         currLatLng = latLng;

         //don't use the return value:
         getAddress(latLng);

         //remove this:
         //mMap.addMarker(new MarkerOptions().position(latLng).title(js.getString(0)).draggable(true));//NullPointer
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException p) {
        //todo

    }
public class Async extends AsyncTask<URL, Void, JSONArray> {
    public JSONArray jsonArray;

    @Override
    protected JSONArray doInBackground(URL... params) {
        BufferedReader reader;
        InputStream is;
        try {

            StringBuilder responseBuilder = new StringBuilder();
            HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.connect();
            is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is));
            for (String line; (line = reader.readLine()) != null; ) {
                responseBuilder.append(line).append("\n");
            }
            JSONObject jObj= new JSONObject(responseBuilder.toString());
            jsonArray = jObj.getJSONArray("results");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jsonArray;
    }


    @Override
    protected void onPostExecute(JSONArray jsonArrayResponse) {
        js = jsonArrayResponse;
        try {
            if (js != null) {
              JSONObject jsFirstAddress = js.getJSONObject(0);
              mMap.addMarker(new MarkerOptions().position(currLatLng).title(jsFirstAddress.getString("formatted_address")).draggable(true));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
  public void getAddress(LatLng latLng) throws IOException {
    URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?latlng="+latLng.latitude+","+latLng.longitude+"&key=AIza***********************");
    Async async =new Async();
    async.execute(url);
    //JSONArray response = async.jsonArray;
    //return response;
  }