活动类别:
public class Event {
/** Title of the earthquake event */
public final String title;
/** Number of people who felt the earthquake and reported how strong it was */
public final String numOfPeople;
/** Perceived strength of the earthquake from the people's responses */
public final String perceivedStrength;
/**
* Constructs a new {@link Event}.
*
* @param eventTitle is the title of the earthquake event
* @param eventNumOfPeople is the number of people who felt the earthquake and reported how
* strong it was
* @param eventPerceivedStrength is the perceived strength of the earthquake from the responses
*/
public Event(String eventTitle, String eventNumOfPeople, String eventPerceivedStrength) {
title = eventTitle;
numOfPeople = eventNumOfPeople;
perceivedStrength = eventPerceivedStrength;
}
Utils Class:
public final class Utils {
/** Tag for the log messages */
public static final String LOG_TAG = Utils.class.getSimpleName();
/**
* Query the USGS dataset and return an {@link Event} object to represent a single earthquake.
*/
public static Event fetchEarthquakeData(String requestUrl) {
// Create URL object
URL url = createUrl(requestUrl);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Error closing input stream", e);
}
// Extract relevant fields from the JSON response and create an {@link Event} object
Event earthquake = extractFeatureFromJson(jsonResponse);
// Return the {@link Event}
return earthquake;
}
/**
* Returns new URL object from the given string URL.
*/
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("POST");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {@link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static 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 static Event extractFeatureFromJson(String earthquakeJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(earthquakeJSON)) {
return null;
}
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, number of people, and perceived strength values
String title = properties.getString("title");
String numberOfPeople = properties.getString("felt");
String perceivedStrength = properties.getString("cdi");
// Create a new {@link Event} object
return new Event(title, numberOfPeople, perceivedStrength);
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
MainActivity类:
public class MainActivity extends AppCompatActivity {
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL =
"https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2016-01-01&endtime=2016-05-02&minfelt=50&minmagnitude=5";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Perform the HTTP request for earthquake data and process the response.
Event earthquake = Utils.fetchEarthquakeData(USGS_REQUEST_URL);
// Update the information displayed to the user.
updateUi(earthquake);
}
/**
* Update the UI with the given earthquake information.
*/
private void updateUi(Event earthquake) {
TextView titleTextView = (TextView) findViewById(R.id.title);
titleTextView.setText(earthquake.title);
TextView tsunamiTextView = (TextView) findViewById(R.id.number_of_people);
tsunamiTextView.setText(getString(R.string.num_people_felt_it, earthquake.numOfPeople));
TextView magnitudeTextView = (TextView) findViewById(R.id.perceived_magnitude);
magnitudeTextView.setText(earthquake.perceivedStrength);
}
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="com.example.android.didyoufeelit.MainActivity">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:textAppearance="?android:textAppearanceLarge" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:text="@string/perceived_strength"
android:textAllCaps="true"
android:textAppearance="?android:textAppearanceMedium" />
<TextView
android:id="@+id/perceived_magnitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/magnitude_circle"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="100sp" />
<TextView
android:id="@+id/number_of_people"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingTop="16dp"
android:textAllCaps="true"
android:textAppearance="?android:textAppearanceMedium" />
</LinearLayout>
例外:
java.lang.RuntimeException:无法启动活动 ComponentInfo {com.example.android.didyoufeelit / com.example.android.didyoufeelit.MainActivity}: android.os.NetworkOnMainThreadException com.example.android.didyoufeelit.Utils.makeHttpRequest(Utils.java:96) 在 com.example.android.didyoufeelit.Utils.fetchEarthquakeData(Utils.java:53) 在 com.example.android.didyoufeelit.MainActivity.onCreate(MainActivity.java:38)