Android to Create an Earthquake Viewer APP

The earthquake feed XML is parsed here by the DOM parser

  • Start by creating an Earthquake project featuring an Earthquake Activity.
  • Create a new EarthquakeListFragment that extends ListFragment. This Fragment displays your list of earthquakes.

public class EarthquakeListFragment extends ListFragment {
}

  • Modify the main.xml layout resource to include the Fragment you created in Step 2. Be sure to name it so that you can reference it from the Activity code.
<?xml version=”1.0” encoding=”utf-8”?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
 android:layout_width=”match_parent”
 android:layout_height=”match_parent”>
 <fragment android:name=”com.paad.earthquake.EarthquakeListFragment”
 android:id=”@+id/EarthquakeListFragment”
 android:layout_width=”match_parent” 
 android:layout_height=”match_parent” 
 />
</LinearLayout>
  • Create a new public Quake class. This class will be used to store the details (date, details, location, magnitude, and link) of each earthquake. Override the toString method to provide the string that will be used to represent each quake in the List View.
package com.paad.earthquake;
import java.util.Date;
import java.text.SimpleDateFormat;
import android.location.Location;
public class Quake {
 private Date date;
 private String details;
 private Location location;
 private double magnitude;
 private String link;
 public Date getDate() { return date; }
 public String getDetails() { return details; }
 public Location getLocation() { return location; }
 public double getMagnitude() { return magnitude; }
 public String getLink() { return link; }
 public Quake(Date _d, String _det, Location _loc, double _mag, String _link) {
 date = _d;
 details = _det;
 location = _loc;
 magnitude = _mag;
 link = _link;
 }
 @Override
 public String toString() {
 SimpleDateFormat sdf = new SimpleDateFormat(“HH.mm”);
 String dateString = sdf.format(date);
 return dateString + “: “ + magnitude + “ “ + details;
 }
}
  • In the EarthquakeListFragment, override the onActivityCreated method to store an ArrayList of Quake objects, and bind that to the underlying ListView using an ArrayAdapter:
public class EarthquakeListFragment extends ListFragment {
ArrayAdapter<Quake> aa;
 ArrayList<Quake> earthquakes = new ArrayList<Quake>();
 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
 super.onActivityCreated(savedInstanceState);
 int layoutID = android.R.layout.simple_list_item_1;
 aa = new ArrayAdapter<Quake>(getActivity(), layoutID , earthquakes);
 setListAdapter(aa);
 }
}
  • Start processing the earthquake feed. For this example, the feed used is the one-day USGS feed for earthquakes with a magnitude greater than 2.5. Add the location of your feed as an external string resource. This lets you potentially specify a different feed based on a user’s location
<?xml version=”1.0” encoding=”utf-8”?>
<resources>
 <string name=”app_name”>Earthquake</string>
 <string name=”quake_feed”>
 http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml
 </string>
</resources>
  • Before your application can access the Internet, it needs to be granted permission for Internet access. Add the Internet uses-permission to the manifest:
<uses-permission android:name=”android.permission.INTERNET”/>
  • Returning to the Earthquake List Fragment, create a new refreshEarthquakes method that connects to and parses the earthquake feed. Extract each earthquake and parse the details to obtain the date, magnitude, link, and location. As you finish parsing each earthquake, pass it in to a new addNewQuake method. Note that the addNewQuake method is executed within a Runnable posted from a Handler object. This allows you to execute the refreshEarthquakes method on a background thread before updating the UI within addNewQuake
private static final String TAG = “EARTHQUAKE”;
private Handler handler = new Handler();
public void refreshEarthquakes() {
 // Get the XML
 URL url;
 try {
 String quakeFeed = getString(R.string.quake_feed);
 url = new URL(quakeFeed);
 URLConnection connection;
 connection = url.openConnection();
 HttpURLConnection httpConnection = (HttpURLConnection)connection;
 int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
 InputStream in = httpConnection.getInputStream();
 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 DocumentBuilder db = dbf.newDocumentBuilder();
 // Parse the earthquake feed.
 Document dom = db.parse(in);
 Element docEle = dom.getDocumentElement();
 // Clear the old earthquakes
 earthquakes.clear();
 // Get a list of each earthquake entry.
 NodeList nl = docEle.getElementsByTagName(”entry”);
 if (nl != null && nl.getLength() > 0) {
 for (int i = 0 ; i < nl.getLength(); i++) {
 Element entry = (Element)nl.item(i);
 Element title = (Element)entry.getElementsByTagName(”title”).item(0);
 Element g = (Element)entry.getElementsByTagName(”georss:point”).item(0);
 Element when = (Element)entry.getElementsByTagName(”updated”).item(0);
 Element link = (Element)entry.getElementsByTagName(”link”).item(0);
 String details = title.getFirstChild().getNodeValue();
 String hostname = “http://earthquake.usgs.gov”;
 String linkString = hostname + link.getAttribute(”href”);
 String point = g.getFirstChild().getNodeValue();
 String dt = when.getFirstChild().getNodeValue(); 
 SimpleDateFormat sdf = new SimpleDateFormat(”yyyy-MM-dd’T’hh:mm:ss’Z’”);
 Date qdate = new GregorianCalendar(0,0,0).getTime();
 try {
 qdate = sdf.parse(dt);
 } catch (ParseException e) {
 Log.d(TAG, “Date parsing exception.”, e);
 }
 String[] location = point.split(” ”);
 Location l = new Location(”dummyGPS”);
 l.setLatitude(Double.parseDouble(location[0]));
 l.setLongitude(Double.parseDouble(location[1]));
 String magnitudeString = details.split(” ”)[1];
 int end = magnitudeString.length()-1;
 double magnitude = Double.parseDouble(magnitudeString.substring(0, end));
 details = details.split(”,”)[1].trim();
 final Quake quake = new Quake(qdate, details, l, magnitude, linkString);
 // Process a newly found earthquake
 handler.post(new Runnable() {
 public void run() {
addNewQuake(quake);
 }
 });
 }
 }
 }
 } catch (MalformedURLException e) {
 Log.d(TAG, ”MalformedURLException”);
 } catch (IOException e) {
 Log.d(TAG, ”IOException”);
 } catch (ParserConfigurationException e) {
 Log.d(TAG, ”Parser Configuration Exception”);
 } catch (SAXException e) {
 Log.d(TAG, ”SAX Exception”);
 }
 finally {
 }
}
private void addNewQuake(Quake _quake) {
 // TODO Add the earthquakes to the array list.
}
  • Update the addNewQuake method so that it takes each newly processed quake and adds it to the earthquake Array List. It should also notify the Array Adapter that the underlying data has changed
private void addNewQuake(Quake _quake) {
 // Add the new quake to our list of earthquakes.
 earthquakes.add(_quake);
 // Notify the array adapter of a change.
 aa.notifyDataSetChanged();
}

Modify your onActivityCreated method to call refreshEarthquakes on startup. Network operations should always be performed in a background thread — a requirement that is enforced in API level 11 onwards.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
 super.onActivityCreated(savedInstanceState);
 int layoutID = android.R.layout.simple_list_item_1;
 aa = new ArrayAdapter<Quake>(getActivity(), layoutID , earthquakes);
 setListAdapter(aa);
 Thread t = new Thread(new Runnable() {
 public void run() {
 refreshEarthquakes(); 
 }
 });
 t.start();
}

When you run your project, you should see a List View that features the earthquakes from the last 24 hours with a magnitude greater than 2.5

Android to Create an Earthquake Viewer APP
Android to Create an Earthquake Viewer APP

Leave a Comment