Iker Martinez Gomez Iker Martinez Gomez - 6 months ago 34
Android Question

JSON parser java.lang.NullPointerException

im getting this error, trying to build a JSON parser with a ListView.
I tried this code with another JSON source and it works but with this link crashes:
http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson

I´d love some help :D

Error:

05-21 20:53:32.871 2509-2606/com.ikeres.app.professorearthquake W/System.err: org.json.JSONException: End of input at character 0 of
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONTokener.nextValue(JSONTokener.java:97)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONObject.<init>(JSONObject.java:156)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONObject.<init>(JSONObject.java:173)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity.ParseJSON(MainActivity.java:102)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity.access$200(MainActivity.java:19)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity$GetTerremotos.doInBackground(Mai nActivity.java:70)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity$GetTerremotos.doInBackground(Mai nActivity.java:44)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.lang.Thread.run(Thread.java:818)


Here is the MainActivity:

public class MainActivity extends ListActivity {

// URL to get contacts JSON
private static String url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson";

// JSON Node names
private static final String TAG_FEATURES = "features";
private static final String TAG_PROPERTIES = "properties";
private static final String TAG_LUGAR = "lugar";
private static final String TAG_MAGNITUD = "magnitud";
private static final String TAG_HORA = "hora";


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

// Calling async task to get json
new GetTerremotos().execute();
}

/**
* Async task class to get json by making HTTP call
*/
private class GetTerremotos extends AsyncTask<Void, Void, Void> {

// Hashmap for ListView
ArrayList<HashMap<String, String>> terremotostList;
ProgressDialog pDialog;

@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}

@Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
WebRequest webreq = new WebRequest();

// Making a request to url and getting response
String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET);

Log.d("Response: ", "> " + jsonStr);

terremotostList = ParseJSON(jsonStr);

return null;
}

@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, terremotostList,
R.layout.list_item, new String[]{TAG_LUGAR, TAG_MAGNITUD,
TAG_HORA}, new int[]{R.id.name,
R.id.email, R.id.mobile});

setListAdapter(adapter);
}

}

private ArrayList<HashMap<String, String>> ParseJSON(String json) {
if (json != null) {
try {
// Hashmap for ListView
ArrayList<HashMap<String, String>> studentList = new ArrayList<HashMap<String, String>>();

JSONObject jsonObj = new JSONObject(json);

// Getting JSON Array node
JSONArray terremotos = jsonObj.getJSONArray(TAG_FEATURES);

// looping through All HeartQuakes
for (int i = 0; i < terremotos.length(); i++) {
JSONObject c = terremotos.getJSONObject(i);




// Properties node is JSON Object
JSONObject properties = c.getJSONObject(TAG_PROPERTIES);
String lugar = properties.getString(TAG_LUGAR);
String magnitud = properties.getString(TAG_MAGNITUD);
String hora = properties.getString(TAG_HORA);

// tmp hashmap for single hq
HashMap<String, String> oterremoto = new HashMap<String, String>();

// adding each child node to HashMap key => value
oterremoto.put(TAG_LUGAR, lugar);
oterremoto.put(TAG_MAGNITUD, magnitud);
oterremoto.put(TAG_HORA, hora);


// adding student to hq list
studentList.add(oterremoto);
}
return studentList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
return null;
}
}


}

WebRequest class:

public class WebRequest {

static String response = null;
public final static int GET = 1;
public final static int POST = 2;

//Constructor with no parameter
public WebRequest() {

}

/**
* Making web service call
*
* @url - url to make request
* @requestmethod - http request method
*/
public String makeWebServiceCall(String url, int requestmethod) {
return this.makeWebServiceCall(url, requestmethod, null);
}

/**
* Making service call
*
* @url - url to make request
* @requestmethod - http request method
* @params - http request params
*/
public String makeWebServiceCall(String urladdress, int requestmethod,
HashMap<String, String> params) {
URL url;
String response = "";
try {
url = new URL(urladdress);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setDoInput(true);
conn.setDoOutput(true);

if (requestmethod == POST) {
conn.setRequestMethod("POST");
} else if (requestmethod == GET) {
conn.setRequestMethod("GET");
}

if (params != null) {
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));

StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");

result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}

writer.write(result.toString());

writer.flush();
writer.close();
os.close();
}

int responseCode = conn.getResponseCode();

if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
} else {
response = "";
}
} catch (Exception e) {
e.printStackTrace();
}

return response;
}


}

Answer

Finally got it. Remove the following lines from the WebRequest class:

    conn.setDoInput(true);
    conn.setDoOutput(true);

add the following after conn.setRequestMethod("GET");:

conn.connect();

Now you get JSON out of the API. After that your app would not display anything. That's because your tags are all in spanish and the API is in english so change:

private static final String TAG_LUGAR = "lugar";
private static final String TAG_MAGNITUD = "magnitud";
private static final String TAG_HORA = "hora";

to:

private static final String TAG_LUGAR = "place";
private static final String TAG_MAGNITUD = "mag";
private static final String TAG_HORA = "time";

It works after these changes.