I'm doing a free course on Android development on Udacity. And this is the code of their app that is supposed to get JSON data about an earthquake from the USGS website and display it in the app. However, for some reason it doesn't. What can be the reason?
P.S. I'm using an Android Emulator and don't have a real device. Could this be a reason?
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.soonami;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
/**
* Displays information about a single earthquake.
*/
public class MainActivity extends AppCompatActivity {
/** Tag for the log messages */
public static final String LOG_TAG = MainActivity.class.getSimpleName();
/** URL to query the USGS dataset for earthquake information */
private static final String USGS_REQUEST_URL =
"https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=2014-12-01&minmagnitude=7";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Kick off an {@link AsyncTask} to perform the network request
TsunamiAsyncTask task = new TsunamiAsyncTask();
task.execute();
}
/**
* Update the screen to display information from the given {@link Event}.
*/
private void updateUi(Event earthquake) {
// Display the earthquake title in the UI
TextView titleTextView = (TextView) findViewById(R.id.title);
titleTextView.setText(earthquake.title);
// Display the earthquake date in the UI
TextView dateTextView = (TextView) findViewById(R.id.date);
dateTextView.setText(getDateString(earthquake.time));
// Display whether or not there was a tsunami alert in the UI
TextView tsunamiTextView = (TextView) findViewById(R.id.tsunami_alert);
tsunamiTextView.setText(getTsunamiAlertString(earthquake.tsunamiAlert));
}
/**
* Returns a formatted date and time string for when the earthquake happened.
*/
private String getDateString(long timeInMilliseconds) {
SimpleDateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy 'at' HH:mm:ss z");
return formatter.format(timeInMilliseconds);
}
/**
* Return the display string for whether or not there was a tsunami alert for an earthquake.
*/
private String getTsunamiAlertString(int tsunamiAlert) {
switch (tsunamiAlert) {
case 0:
return getString(R.string.alert_no);
case 1:
return getString(R.string.alert_yes);
default:
return getString(R.string.alert_not_available);
}
}
/**
* {@link AsyncTask} to perform the network request on a background thread, and then
* update the UI with the first earthquake in the response.
*/
private class TsunamiAsyncTask extends AsyncTask<URL, Void, Event> {
@Override
protected Event doInBackground(URL... urls) {
// Create URL object
URL url = createUrl(USGS_REQUEST_URL);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = "";
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
// Extract relevant fields from the JSON response and create an {@link Event} object
Event earthquake = extractFeatureFromJson(jsonResponse);
// Return the {@link Event} object as the result fo the {@link TsunamiAsyncTask}
return earthquake;
}
/**
* Update the screen with the given earthquake (which was the result of the
* {@link TsunamiAsyncTask}).
*/
@Override
protected void onPostExecute(Event earthquake) {
if (earthquake == null) {
return;
}
updateUi(earthquake);
}
/**
* Returns new URL object from the given string URL.
*/
private URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} catch (IOException e) {
// TODO: Handle the exception
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {@link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return an {@link Event} object by parsing out information
* about the first earthquake from the input earthquakeJSON string.
*/
private Event extractFeatureFromJson(String earthquakeJSON) {
try {
JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);
JSONArray featureArray = baseJsonResponse.getJSONArray("features");
// If there are results in the features array
if (featureArray.length() > 0) {
// Extract out the first feature (which is an earthquake)
JSONObject firstFeature = featureArray.getJSONObject(0);
JSONObject properties = firstFeature.getJSONObject("properties");
// Extract out the title, time, and tsunami values
String title = properties.getString("title");
long time = properties.getLong("time");
int tsunamiAlert = properties.getInt("tsunami");
// Create a new {@link Event} object
return new Event(title, time, tsunamiAlert);
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
}
}