Archive

Posts Tagged ‘xmlpullparser’

How to verify an RSS Feed if New Articles have been published.

March 26, 2012 3 comments

Recently I built an rss app for a site that publishes daily IT News – ITMoldova.com. The main feature of application is to launch a service in background (at a given interval of time), and check if new articles have been published on http://itmoldova.com site. If it turns out that new articles have been published, then fire a notification message and notify the user about this, something like this: “4 New Articles Published on ITMoldova.com”.

How to identify how many articles were published?

The mechanism to identify if new articles have been published on the site (and how many) is pretty straightforward: when the application is installed and launched for the first time, it parses the Rss Feed and creates a new entry in the SharedPreferences with the value of <pubDate> element, of the first item from the rss list (pubDate = publication date). Then, everytime the service starts, it parses the RSS Feed and checks the value of first item from the rss list against the value stored in SharedPreferences, if the value stored in SharedPreferences is less than value returned by the service, then it means that there are new articles and it’s time to notify the user! Lastly, update the SharedPreferences with the most recent pubDate.

For the sake of simplicity and keeping things consistent, I will post here only snippets of most relevant code, but this will be good enough to give you an idea about how things works.

How to compare two dates?

To compare the dates we need to convert them to milliseconds. The getTime() method of Date class can help us return the number of milliseconds of a given date:

Date date=new Date();
int timeMilliseconds=date.getTime();

 

Below is the implementation of verifyDates(String, String) method that will be used by the Service. The method takes 2 string parameters, the pubDate of rss item, and the pubDate stored in SharedPreferences.


public class Tools {
  public int newArticles;
  public boolean hasMoreArticles = true;

  public void verifyDates(String rssPubDate, String sharedPrefLastPubDate) {
    if (hasMoreArticles) {
      SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
      Date dLastPubDate = null;
      Date dRssPubDate = null;

      try {
        dLastPubDate = df.parse(sharedPrefLastPubDate.substring(5));
        dRssPubDate = df.parse(rssPubDate.substring(5));
      } catch (ParseException e) {
        Log.d("GREC", "Exception in verifayDates: " + e.getMessage());
        e.printStackTrace();
      }

      //We want to count how many new articles were published.
      if (dRssPubDate.getTime() > dLastPubDate.getTime()) {
        newArticles++;
      } else {
        hasMoreArticles = false;
      }
    }
  }

}
The Service Implementation

The service will parse the Rss Feed and do the comparison. Also, it will launch a status bar notification if it turns out that new articles were published.

public class RssService extends IntentService {

  public RssService() {
    super("ITMoldovaRssService");
  }

  @Override
  protected void onHandleIntent(Intent intent) {

    // Retrieve the date from SharedPreferences
    String lastPubDate = getDateFromSharedPrefs();

    // The AndroidFeedParser class helps us parse the Rss Feed.
    AndroidFeedParser parser;

    try {
      parser = new AndroidFeedParser(new URL("http://itmoldova.com/feed/"));
      List<Message> list = parser.parse();

      if (list != null) {
        for (int i = 0; i < list.size(); i++) {

          // Verify the pubDate of each item, against pubDate stored in SharedPreferences
          tools.verifyDates(list.get(i).getDate(), lastPubDate);
        }

        // Get the last pubDate and save it to SharedPreferences.
        lastPubDate = list.get(0).getDate();
        saveToSharedPreferences(lastPubDate);
      }
    } catch (MalformedURLException e) {
      Log.d("GREC", "Malformed URL Exception: " + e.getMessage());
      e.printStackTrace();
    }

    if (tools.newArticles > 0) {
      displayNotification();
    } else {
      Log.d("GREC", "No new articles ");
    }
  }
}

 

The service begins with parsing the Rss Feed and return the list of items:

List<Message> list = parser.parse();

then iterate through it comparing the publication date:

for (int i = 0; i < list.size(); i++) {
    // Verify the pubDate of each item, against pubDate stored in SharedPreferences
    tools.verifyDates(list.get(i).getDate(), lastPubDate);
}

and then ends getting the most recent publication date and saving it to SharedPreferences:

// Get the last pubDate and save it to SharedPreferences.
lastPubDate = list.get(0).getDate();
saveToSharedPreferences(lastPubDate);

If it turns out that new articles were published, display a status bar notification.

if (tools.newArticles > 0) {
displayNotification();
}

 

How to parse an XML feed and how to display a status bar notification are some helper topics you may need to take a look in order to fully complete this task.

Parsing XML with XmlPullParser

January 17, 2012 6 comments

XmlPullParser is an interface that provides parsing functionality. The below code is an example of XmlPullParser usage.

We will parse the Youtube feed that contains the most highly rated YouTube video, looking for “<title>” tag and extracting the text inside.

URL Feed: https://gdata.youtube.com/feeds/api/standardfeeds/top_rated


//We will put the data into a StringBuilder
StringBuilder builder=new StringBuilder();

URL url = new URL("https://gdata.youtube.com/feeds/api/standardfeeds/top_rated");

XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp=factory.newPullParser();

xpp.setInput(getInputStream(url), "UTF_8");

int eventType=xpp.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
  // Looking for a start tag
  if(eventType==XmlPullParser.START_TAG){
    //We look for "title" tag in XML response
    if(xpp.getName().equalsIgnoreCase("title")){
      //Once we found the "title" tag, add the text it contains to our builder
      builder.append(xpp.nextText()+"\n");
    }
  }

  eventType=xpp.next();
}

And here’s the implementation of getInputStream() method:

public InputStream getInputStream(URL url) {
  try {
    return url.openConnection().getInputStream();
  } catch (IOException e) {
    return null;
  }
}
Follow

Get every new post delivered to your Inbox.

Join 516 other followers

%d bloggers like this: