【问题标题】:Google maps reverse geocoding via HTTPS in AndroidGoogle 在 Android 中通过 HTTPS 映射反向地理编码
【发布时间】:2015-11-11 03:31:46
【问题描述】:

我正在制作谷歌地图应用程序。由于 Geocoder 类返回空(在 [0] 处超出范围),我目前正在尝试 HTTPS Google 地图反向地理编码。 这是我的 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;
}

这是 Async 子类:

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

和 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" />

点击方法:

@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

    }

4 天以来,我试图获得与 NullPointerException 不同的东西。知道我在做什么错吗?在以调试模式连接的平板电脑上进行了测试。 任何帮助都会很有用。我很绝望。

【问题讨论】:

  • 您需要等到 AsyncTask 完成后才能使用 JSONArray。 AsyncTask 是您的 Activity 的子类吗?另外,你在哪里使用js
  • 是的。如何等待?标记标题中的 js。我知道这不是解析的方式,但我会在获得 [0] 中的值后修复它
  • 使用 onPostExecute 方法。显示您当前在哪里使用js
  • mMap.addMarker(new MarkerOptions().position(latLng).title(js.getString(0)).draggable(true));
  • 复制代码到 PostExecute?

标签: android google-maps https google-maps-android-api-2


【解决方案1】:

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

然后,在 onPostExecute() 中添加 Marker。

首先,Activity代码的变化。 在 JSONArray 之外创建一个 LatLng 成员变量:

public class MyMapActivity extends AppCompatActivity implements OnMapReadyCallback
{

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

然后,修改onMapClick,将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();
        }
    }
}

请注意,您不需要从 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;
    //return response;
  }

【讨论】:

  • 仍然得到一个 NullPointer ,再次在 marker:title(js.getString(0)) 这次 onPostExecute 它现在在哪里
  • @fixxxera 我刚刚运行了代码,并意识到响应是一个包含 JSONArray 的 JSONObject,这就是为什么当您尝试使用结果创建 JSONArray 时它为空的原因。用修改后的 AsyncTask 查看更新的答案。
  • 谢谢你!我到了一半(Api 密钥不是我需要的那个,尝试了 JsonObj,它给了我无效 IP 密钥的 IP 错误)仍然你救了我的一天!谢谢!
猜你喜欢
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2020-06-05
  • 2012-01-29
相关资源
最近更新 更多