Sunday, January 13, 2013

Android working with the RSS feed

make a project with the name Earthquake, create a main activity class with the name Earthquake.java with following code


package jitesh.example.earthquake;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.location.Location;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class Earthquake extends Activity {
 
  ListView earthquakeListView;
  ArrayAdapter<Quake> aa;
  ArrayList<Quake> earthquakes = new ArrayList<Quake>();
     
  static final private int QUAKE_DIALOG = 1;
  Quake selectedQuake;

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
   
    earthquakeListView = (ListView)this.findViewById(R.id.earthquakeListView);

    earthquakeListView.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {
          selectedQuake = earthquakes.get(_index);
          showDialog(QUAKE_DIALOG);
        }
      });
   
    int layoutID = android.R.layout.simple_list_item_1;
    aa = new ArrayAdapter<Quake>(this, layoutID , earthquakes);
    earthquakeListView.setAdapter(aa);
   
    refreshEarthquakes();
  }
 
  private 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) {
           e.printStackTrace();
         }

         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();
           
         Quake quake = new Quake(qdate, details, l, magnitude, linkString);

         // Process a newly found earthquake
         addNewQuake(quake);
       }
     }
   }
 } catch (MalformedURLException e) {
   e.printStackTrace();
 } catch (IOException e) {
   e.printStackTrace();
 } catch (ParserConfigurationException e) {
   e.printStackTrace();
 } catch (SAXException e) {
   e.printStackTrace();
 }
 finally {
 }
}

    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();
}
   
    static final private int MENU_UPDATE = Menu.FIRST;
   
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
      super.onCreateOptionsMenu(menu);

      menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update);
                 
      return true;
    }
           
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
      super.onOptionsItemSelected(item);
         
      switch (item.getItemId()) {
        case (MENU_UPDATE): {

          refreshEarthquakes();
          return true;
        }
      }
      return false;
    }
   
    @Override
    public Dialog onCreateDialog(int id) {
      switch(id) {
        case (QUAKE_DIALOG) :
          LayoutInflater li = LayoutInflater.from(this);
          View quakeDetailsView = li.inflate(R.layout.quake_details, null);

          AlertDialog.Builder quakeDialog = new AlertDialog.Builder(this);
          quakeDialog.setTitle("Quake Time");
          quakeDialog.setView(quakeDetailsView);
          return quakeDialog.create();
      }
      return null;
    }

    @Override
    public void onPrepareDialog(int id, Dialog dialog) {
      switch(id) {
        case (QUAKE_DIALOG) :
          SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
          String dateString = sdf.format(selectedQuake.getDate());
          String quakeText = "Magnitude " + selectedQuake.getMagnitude() +
                             "\n" + selectedQuake.getDetails()  + "\n" +
                             selectedQuake.getLink();

          AlertDialog quakeDialog = (AlertDialog)dialog;
          quakeDialog.setTitle(dateString);
          TextView tv = (TextView)quakeDialog.findViewById(R.id.quakeDetailsTextView);
          tv.setText(quakeText);

          break;
      }
    }
   
}

the main.xml is having the code as below


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <ListView
    android:id="@+id/earthquakeListView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
  />
</LinearLayout>

make a java class with name Quake.java with the given code


package jitesh.example.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;
  }
}





the quake_details.xml is having the layout as follows


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:padding="10dp">
  <TextView
    android:id="@+id/quakeDetailsTextView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textSize="14sp"
    android:autoLink="all"
  />
</LinearLayout>

after it go through the strings.xml and copy the following lines


<?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>
  <string name="menu_update">Refresh Earthquakes</string>
</resources>

beside this have a look on manifes


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jitesh.example.earthquake"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Earthquake"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="7" />
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>






No comments:

Post a Comment