无法解析嵌套的JSON对象

时间:2017-07-27 12:43:45

标签: android

我想检索“opening_hour”对象并解析“open_now”数组。但由于某种原因我无法做到这一点,可能是我的解析层次结构错了。有人可以建议,应该怎么做。以下是我的JSON链接:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=12.9647254,77.7191899&radius=500&name=cafe&key=AIzaSyD_kA7xtNYffQNlykVkVGk5ZNQgQtZFZTk

 if (status == 200) {
                HttpEntity entity = response.getEntity();
                String data = EntityUtils.toString(entity);

                JSONObject jsono = new JSONObject(data);
                JSONArray jarray = jsono.getJSONArray("results");

                for (int i = 0; i < jarray.length(); i++) {
                    JSONObject object = jarray.getJSONObject(i);

                    Elements parameters = new Elements();

                    parameters.setTitle(object.getString("name"));
                    parameters.setImage(object.getString("icon"));

                    elementList.add(parameters);
                }

                JSONArray jarraytwo = jsono.getJSONArray("opening_hours");

                for (int i = 0; i < jarraytwo.length(); i++) {
                    JSONObject objecttwo = jarraytwo.getJSONObject(i);

                    Elements parameterstwo = new Elements();

                    parameterstwo.setAuthor(objecttwo.getString("open_now"));

                    Toast.makeText(getApplicationContext(), "open_now : " + objecttwo.getString("open_now"), Toast.LENGTH_LONG).show();

                    elementListtwo.add(parameterstwo);
                }

                return true;

这是我所知道的愚蠢问题,但我不知道嵌套的json解析。以下是我的完整代码和我传递的链接

public class MainActivity extends AppCompatActivity {

    private static final int REQ_CODE_SPEECH_INPUT = 100;
    private TextView mVoiceInputTv;
    private ImageButton mSpeakBtn;

    private static final int PERMISSION_ACCESS_COARSE_LOCATION = 1;
    private GoogleApiClient googleApiClient;

    int status;

    ArrayList<String> result;

    ArrayList<Elements> elementList;
    ArrayList<Elements> elementListtwo;
    ElementAdaptor adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //mVoiceInputTv = (TextView) findViewById(R.id.voiceInput);
        mSpeakBtn = (ImageButton) findViewById(R.id.btnSpeak);
        mSpeakBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                startVoiceInput();
            }
        });

    }

    private void startVoiceInput() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Welcome to Harman Framework");
        try {
            startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
        } catch (ActivityNotFoundException a) {

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case REQ_CODE_SPEECH_INPUT: {
                if (resultCode == RESULT_OK && null != data) {
                    result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                    //mVoiceInputTv.setText(result.get(0));
                    Toast.makeText(getApplicationContext(), "You searched : " + result.get(0), Toast.LENGTH_LONG).show();

                    elementList = new ArrayList<Elements>();

                    new JSONAsyncTask().execute("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670,151.1957&radius=500&types=food&name=" + result.get(0) + "&key=AIzaSyD_kA7xtNYffQNlykVkVGk5ZNQgQtZFZTk");

                    ListView listview = (ListView)findViewById(R.id.list);
                    adapter = new ElementAdaptor(getApplicationContext(), R.layout.row, elementList);

                    listview.setAdapter(adapter);

                    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                        @Override
                        public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                                                long id) {
                            Intent intent = new Intent(getApplicationContext(), DescriptionActivity.class);
                            intent.putExtra("title", elementList.get(position).getTitle());
                            intent.putExtra("author", elementList.get(position).getAuthor());
                            intent.putExtra("publishedat", elementList.get(position).getPublishedat());
                            intent.putExtra("description", elementList.get(position).getDescription());
                            intent.putExtra("imageurl", elementList.get(position).getImage());
                            startActivity(intent);
                        }
                    });

                }
                break;
            }

        }
    }

    //String url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670,151.1957&radius=500&types=food&name=" + result.get(0) + "&key=AIzaSyD_kA7xtNYffQNlykVkVGk5ZNQgQtZFZTk";

    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setMessage("Loading.......");
            dialog.setTitle("Connecting server");
            dialog.show();
            dialog.setCancelable(false);
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {

                HttpGet httppost = new HttpGet(urls[0]);

                HttpParams httpParameters = new BasicHttpParams();

                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);
                HttpParams params = httpclient.getParams();

                status = response.getStatusLine().getStatusCode();

                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);

                    JSONObject jsono = new JSONObject(data);
                    JSONArray jarray = jsono.getJSONArray("results");

                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);

                        Elements parameters = new Elements();

                        parameters.setTitle(object.getString("name"));
                        parameters.setImage(object.getString("icon"));

                        elementList.add(parameters);

                    }
                    return true;
                }

            }  catch (JSONException e3) {
                e3.printStackTrace();
            }  catch (IOException e2) {
                e2.printStackTrace();
            }

            return false;
        }

        protected void onPostExecute(Boolean result) {
            dialog.cancel();
            adapter.notifyDataSetChanged();
            if(result == false)
                Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();

        }
    }
}

3 个答案:

答案 0 :(得分:1)

您需要将for循环嵌套到彼此中。看看你的JSON文件的结构:你有jarray,它是一个JSON对象数组。阵列中的每个JSON对象都有自己的开放时间。所以你想要这样的事情:

for (int i = 0; i < jarray.length(); i++) {
    JSONObject object = jarray.getJSONObject(i);

    Elements parameters = new Elements();

    parameters.setTitle(object.getString("name"));
    parameters.setImage(object.getString("icon"));

    elementList.add(parameters);

    // Get opnening hours for current result
    JSONObject curOpeningHours = object.getJSONObject("opening_hours");
    hoursList.push(curOpeningHours);

    String openNow = curOpeningHours.getString("open_now");
    // Do something...

}

它没有测试这个,但它应该给你一个想法

答案 1 :(得分:0)

使用嵌套的JSONObject

        JSONArray jarray = jsono.getJSONArray("results");
            for (int i = 0; i < jarray.length(); i++) {
                 JSONObject object = jarray.getJSONObject(i);
                 JSONArray jarray1 = object.getJSONArray("opening_hours");
             for (int j = 0; j < jarray1.length(); j++) {
                JSONObject object2 = jarray1.getJSONObject(j);                         
               parameters.setOpenNow(object2.getString("open_now"));                   
            }
           }

答案 2 :(得分:0)

在解析复杂的json时,或者如果json至少包含一个对象数组,我根本不会使用JSONObject。 而是使用google-gson

使用gson,您可以用更少的代码和精力序列化/反序列化您的json。

我首先创建一个java类,代表您尝试解析的相同json方案。

例如,尝试解析此JSon字符串:

[
 {
  "FirstName": "What",
  "LastName": "Ever"
 },
 {
  "FirstName": "John",
  "LastName": "Snow"
 }
]

在java代码中,我首先创建一个类:

public class Person {
   public String FirstName;
   public String LastName;
}

现在解析json:

Gson gson = new Gson();
List<Person> people = gson.fromJson("Json string here", new TypeToken<List<Person>>() {}.getType());

现在你可以在列表上做一个循环,找到John Snow。