0

I have json that looks likes this:

{"type":"FeatureCollection","metadata":{"generated":1428783374000,"url":"http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2015-04-04&endtime=2015-04-05","title":"USGS Earthquakes","status":200,"api":"1.0.17","count":328},"features":[{"type":"Feature","properties":{"mag":1.3,"place":"8km SSE of Talmage, California","time":1428191575500,"updated":1428359465102,"tz":-420,"url":"http://earthquake.usgs.gov/earthquakes/eventpage/nc72426686","detail":"http://earthquake.usgs.gov/fdsnws/event/1/query?eventid=nc72426686&format=geojson","felt":null,"cdi":null,"mmi":null,"alert":null,"status":"reviewed","tsunami":0,"sig":26,"net":"nc","code":"72426686","ids":",nc72426686,","sources":",nc,","types":",cap,general-link,geoserve,nearby-cities,origin,phase-data,scitech-link,tectonic-summary,","nst":12,"dmin":0.08508,"rms":0.06,"gap":154,"magType":"md","type":"earthquake","title":"M 1.3 - 8km SSE of Talmage, California"},"geometry":{"type":"Point","coordinates":[-123.1233333,39.0688333,7.27]},"id":"nc72426686"},

My Main Activity code looks like this:

public class MainActivity extends ActionBarActivity {

private static final String LOG_TAG ="JSON STRING";
TextView httpData;
HttpClient client;
JSONObject json;


final static String URL = "http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2015-04-04&endtime=2015-04-05";

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

    httpData = (TextView) findViewById(R.id.tvHttp);
    client = new DefaultHttpClient();

    new Read().execute("features");

}

public JSONObject lastEvent(String event) throws ClientProtocolException, IOException, JSONException {
    StringBuilder url = new StringBuilder(URL);

    HttpGet get = new HttpGet(url.toString());
    HttpResponse response = client.execute(get);

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

    if ( status == 200 ) {
        HttpEntity entity = response.getEntity();
        String data = EntityUtils.toString(entity);
        JSONArray timeline = new JSONArray(data);
        JSONObject last = timeline.getJSONObject(0);

        return last;
    }
    else {
        Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT);
        return null;
    }
}


public class Read extends AsyncTask<String, Integer, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            json = lastEvent("title");
            return json.getString(params[0]);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result ) {
       httpData.setText(result);
    }
}

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

}

My activity_main.xml looks like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<ScrollView android:layout_height="fill_parent" android:layout_width="fill_parent">
<TextView android:text="Loading Data" android:id="@+id/tvHttp" android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</ScrollView>

I am trying to get the value of 'title' from the first element of the JSONArray, but instead I just get a blank Text View screen. I am somewhat new to Java and Android in general, so if a different format (such as XML) is easier for me to work with, I can try that too. Any insight or hints is greatly appreciated.

4
  • Either I misunderstood it, or I'm unsure why this doesn't throw errors. If the above JSON Format is everything you've got, you'll need to create a JSONObject and then you can use getString("title"). You however create a JSONArray. Commented Apr 12, 2015 at 13:05
  • You're saying I should not create the JSONArray and just get it straight from the JSONObject? Commented Apr 12, 2015 at 13:11
  • Okay, I just reread you question. Are you trying to get the title from the outer most object? Or are you trying to get a field of the features array? Commented Apr 12, 2015 at 13:21
  • A field from the features array- the 'title' field for now. Commented Apr 12, 2015 at 13:24

1 Answer 1

1

Okay, assuming we have the JSON you posted

{"type":"FeatureCollection","metadata":{"generated":1428783374000,"url":"http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2015-04-04&endtime=2015-04-05","title":"USGS Earthquakes","status":200,"api":"1.0.17","count":328},"features":[{"type":"Feature","properties":{"mag":1.3,"place":"8km SSE of Talmage, California","time":1428191575500,"updated":1428359465102,"tz":-420,"url":"http://earthquake.usgs.gov/earthquakes/eventpage/nc72426686","detail":"http://earthquake.usgs.gov/fdsnws/event/1/query?eventid=nc72426686&format=geojson","felt":null,"cdi":null,"mmi":null,"alert":null,"status":"reviewed","tsunami":0,"sig":26,"net":"nc","code":"72426686","ids":",nc72426686,","sources":",nc,","types":",cap,general-link,geoserve,nearby-cities,origin,phase-data,scitech-link,tectonic-summary,","nst":12,"dmin":0.08508,"rms":0.06,"gap":154,"magType":"md","type":"earthquake","title":"M 1.3 - 8km SSE of Talmage, California"},"geometry":{"type":"Point","coordinates":[-123.1233333,39.0688333,7.27]},"id":"nc72426686"},

It's an object. We want to get into the array in key features, and we want the title key in the first element (which is an object) of that array.


Looking at your lastEvent function. You pass a String called event. But that is never used.

public String lastEvent(String event) throws ClientProtocolException, IOException, JSONException {
    StringBuilder url = new StringBuilder(URL);

    HttpGet get = new HttpGet(url.toString());
    HttpResponse response = client.execute(get);

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

    if ( status == 200 ) {
        HttpEntity entity = response.getEntity();
        String data = EntityUtils.toString(entity);
        // data now contains the json object I posted above
        // So we fetch it
        JSONObject timeline = new JSONObject(data);
        // We want the features array
        JSONArray features = timeline.getJSONArray("features");
        // The first element
        JSONObject first = timeline.getJSONObject(0);
        // The titles attribute. I assume lastEvent("titles")
        // is the way you call this function
        String last = first.getString(event);

        return last;
    }
    else {
        Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT);
        return null;
    }
}

Note I changed the return type of lastEvent, because we are getting a String from the object. The first parameter event now is for the field we want to get, I think that was your intention, because you call it like that in the AsyncTask.


Also, check your Logcat! A JSONException might be thrown, that you catch and print its message and return null. Returning null, and later calling httpData.setText(null) would result in an empty TextView


Edit: Also your doInBackground function doesn't need to call getString() anymore on the return value of lastEvent. I don't know how generic your AsyncTask needs to be. But the code I wrote might help you to get where you want to be.

Sign up to request clarification or add additional context in comments.

2 Comments

Ah, that makes more sense. I am still not quite there though. Do I need to modify my AsyncTask to return a String instead of JSONObject?
@perlsufi yes, because my changes lead to directly getting the content of title, which is a String.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.