创建Json请求并获取Json对象

时间:2014-02-18 15:46:39

标签: android json google-places-api

我与this tutorial一起关注如何在Android中自动完成使用Google Places API。

这将获得预测的描述,并将它们存储在一个数组中,以便在用户输入其字符串时显示。

private ArrayList<String> autocomplete(String input) {
        ArrayList<String> resultList = null;

        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();
        try {
            URL mUrl = new URL(PLACES_API_BASE +
                    TYPE_AUTOCOMPLETE +
                    OUT_JSON +
                    "?sensor=false&key=" +
                    API_KEY +
                    "&components=country:us" +
                    "&input=" +
                    URLEncoder.encode(input, "utf8"));

            conn = (HttpURLConnection) mUrl.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());

            // Load the results into a StringBuilder
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
            return null;
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error connecting to Places API", e);
            return null;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

        try {
            // Create a JSON object hierarchy from the results
            JSONObject jsonObj = new JSONObject(jsonResults.toString());
            mPredictionsJsonArray = jsonObj.getJSONArray("predictions");

            // Extract the Place descriptions from the results
            resultList = new ArrayList<String>(mPredictionsJsonArray.length());
            for (int i = 0; i < mPredictionsJsonArray.length(); i++) {
                resultList.add(mPredictionsJsonArray.getJSONObject(i).getString("description"));
            }
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

        return resultList;
    }

然后,当用户点击建议时;

@Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
        //String reference = "https://maps.googleapis.com/maps/api/place/details/json?reference=";
        //String photo = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=70&photoreference=";

        try {
            REFERENCE = mPredictionsJsonArray.getJSONObject(position).getString("reference");
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
        }

        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();

        try {
            REFERENCE = mPredictionsJsonArray.getJSONObject(position).getString("reference");
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
        }

        try {
            URL mUrl = new URL("https://maps.googleapis.com/maps/api/place/details/json?reference=" +
                    REFERENCE +
                    "?sensor=false&key=" +
                    API_KEY);

            conn = (HttpURLConnection) mUrl.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());

            // Load the results into a StringBuilder
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }

        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error connecting to Places API", e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

logcat的

02-18 10:59:27.775    2081-2081/com.example.project.thisthat E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.project.thisthat, PID: 2081
    android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
            at com.android.org.conscrypt.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:1009)
            at com.android.okhttp.Connection.close(Connection.java:175)
            at com.android.okhttp.internal.Util.closeQuietly(Util.java:110)
            at com.android.okhttp.internal.http.HttpEngine.release(HttpEngine.java:447)
            at com.android.okhttp.internal.http.HttpURLConnectionImpl.disconnect(HttpURLConnectionImpl.java:104)
            at com.android.okhttp.internal.http.HttpsURLConnectionImpl.disconnect(HttpsURLConnectionImpl.java:124)
            at com.example.project.thisthat.PollActivity.onItemClick(PollActivity.java:175)
            at android.widget.AutoCompleteTextView.performCompletion(AutoCompleteTextView.java:902)
            at android.widget.AutoCompleteTextView.access$500(AutoCompleteTextView.java:91)
            at android.widget.AutoCompleteTextView$DropDownItemClickListener.onItemClick(AutoCompleteTextView.java:1192)
            at android.widget.AdapterView.performItemClick(AdapterView.java:299)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
            at android.widget.AbsListView$3.run(AbsListView.java:3638)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)

我能够获取所选项目的参考编号,但是,当我尝试在onItemClick()函数中复制上述代码时,我收到致命错误并且应用程序强制关闭。 我正在尝试最终获得所选地点的照片网址。

2 个答案:

答案 0 :(得分:1)

正如其他人所提到的,你当然可以在每个OnItemClick中创建一个新的AsyncTask。在幕后,Android系统无论如何共享AsyncTasks的线程。

答案 1 :(得分:0)

你得到了:

android.os.NetworkOnMainThreadException

这意味着您正在尝试在主线程上执行网络调用,最好的方法是使用Asynctask并获取asyncTask中的数据,然后从asynctask的onPostExecute()方法发送数据到主线程,以便更新UI。

asyncTask参考[1],[2]。

[1] http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html

[2] http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html#.UwQ2J2KSx1Y