Google地图通过Android中的HTTPS反向地理编码 [英] Google maps reverse geocoding via HTTPS in Android

查看:170
本文介绍了Google地图通过Android中的HTTPS反向地理编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public JSONArray getAddress(LatLng latLng)throws IOException {
URL 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;

返回响应;



$ b

这是Async子类:

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

尝试{

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(\\\
);
}
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;
}

和manifest.xml:

 < uses-permission android:name =android.permission.ACCESS_COARSE_LOCATION/> 
< uses-permission android:name =android.permission.ACCESS_FINE_LOCATION/>
< uses-permission android:name =android.permission.INTERNET/>
< uses-permission android:name =android.permission.WRITE_EXTERNAL_STORAGE/>
< uses-permission android:name =android.permission.ACCESS_NETWORK_STATE/>

Onclick方法:

  @Override 
public void onMapClick(LatLng latLng){
JSONArray js = null;
尝试{
js = getAddress(latLng);
mMap.addMarker(new MarkerOptions()。position(latLng).title(js.getString(0))。draggable(true)); // NullPointer
} catch(IOException e){
e.printStackTrace();
} catch(JSONException p){
// todo

}

4天后,我试图获得与NullPointerException不同的内容。任何想法我做错了什么?在以调试模式连接的平板电脑上测试。
任何帮助都会有用。我非常绝望。

解决方案

由于AsyncTask是Activity的子类,因此您只需将LatLng分配给Activity的成员变量它可以在AsyncTask中访问。

然后,将标记添加到onPostExecute()。



首先,更改为活动代码。
除JSONArray之外,还创建一个LatLng成员变量:

  public class MyMapActivity extends AppCompatActivity implements OnMapReadyCallback 
{

JSONArray js;
LatLng currLatLng;
// ...............

然后,修改onMapClick以将LatLng分配给实例变量:

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

//分配给成员变量:
currLatLng = latLng;

//不使用返回值:
getAddress(latLng);

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

}

然后,在获得响应后,使用onPostExecute放置标记。
另一个主要问题是JSON响应是一个包含JSONArray的JSONObject。
在以下代码中修复:

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

@Override
protected JSONArray doInBackground(URL ... params){
BufferedReader reader;
InputStream是;
尝试{

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(\\\
);
}
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;
尝试{
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();
}
}
}

请注意,需要从getAddress()返回任何东西,所以只需要返回类型 void ,然后让AsyncTask执行其余部分:

  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;
//返回响应;
}


I am making google map app. Since Geocoder class returns empty(out of bounds at [0]) i am currently trying the HTTPS Google maps reverse GeoCoding. This is my onClick call:

  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;
}

This is the Async subclass:

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;
    }

and manifest.xml:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Onclick method :

@Override
public void onMapClick(LatLng latLng) {
    JSONArray js=null;
    try {
         js = getAddress(latLng);
         mMap.addMarker(new MarkerOptions().position(latLng).title(js.getString(0)).draggable(true));//NullPointer
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException p) {
        //todo

    }

For 4 days now i am trying to get something different than NullPointerException. Any idea what am i doing wrong? Tested on tablet connected in debug mode. Any help will be useful. I am quite desperate.

解决方案

Since the AsyncTask is a subclass of the Activity, you just need to assign the LatLng to a member variable of the Activity so that it's accessible in the AsyncTask.

Then, add the Marker in onPostExecute().

First, the change to the Activity code. Make a LatLng member variable in addition to the JSONArray:

public class MyMapActivity extends AppCompatActivity implements OnMapReadyCallback
{

    JSONArray js;
    LatLng currLatLng;
    //...............

Then, modify the onMapClick to assign the LatLng to the instance variable:

@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

    }

Then, use onPostExecute to place the marker after you have the response. The other main issue is that the JSON response is a JSONObject that contains a JSONArray inside it. Fixed in the code below:

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();
        }
    }
}

Note that you don't need to return anything from getAddress(), so just make the return type void and let the AsyncTask do the rest once it's executed:

  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;
  }

这篇关于Google地图通过Android中的HTTPS反向地理编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆