[Android] Downloading and Displaying RSS Content

RSS feeds list the latest content added to a site. The sample in this post demonstrates how to obtain RSS content and display the latest item. It will cover:

The sample code can be downloaded from the GitHub repository.



Downloading the RSS

To download RSS content, the app must first have the INTERNET permission. Declaring this in the manifest:

...
<manifest ...>
    ...
    <uses-permission android:name="android.permission.INTERNET" />
...
</manifest>

The demo activity contains only a WebView, so it may as well download the content when the activity starts:

protected void onStart() {
    super.onStart();

    // Downloading the RSS feed needs to be done on a separate thread.
    Thread downloadThread = new Thread(new Runnable() {

        public void run() {
            try {
                updateView(getLatestContent(retrieveRssDocument()));
            } catch (Exception e) {
                Log.e("Content Retriever", e.getLocalizedMessage(), e);
            }
        }
    });

    downloadThread.start();
}

Note that because obtaining data over HTTP can be slow, it must be done on a separate thread. Failure to do so may result in a NetworkOnMainThreadException (at least for API 11 anyway).

To download the content, create an URL based on the location of the RSS content and call its openConnection method and extract the content from an InputStream. Since RSS uses the XML format, the content is read into a Document:

private Document retrieveRssDocument() throws IOException,
        ParserConfigurationException, SAXException {

    URL url = new URL(source);
    URLConnection connection = url.openConnection();
    InputStream inStream = connection.getInputStream();

    try {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder();
        return builder.parse(new BufferedInputStream(inStream));
    } finally {
        inStream.close();
    }
}


Extract an item

RSS uses the XML format and its specification can be found on the RSS Advisory Board. Here is small sample of RSS content:

<?xml version="1.0"?>
<rss version="2.0">
   <channel>
      <title>...(Name for RSS channel)...</title>
      <link>...(Link to the site)...</link>
      <description>...(description for the channel)...</description>

      <item>
         <title>...(item title)...</title>
         <link>...(URL to the story)...</link>
         <description>...(sample content)...</description>
         <pubDate>...(when the item was published)...</pubDate>
         <guid>...(string to identify the item)...</guid>
      </item>

      ...(possibly more items)...
   </channel>
</rss>

An _item_ represents the content that has been added, such as a post, comment or article. Earlier, the content has already been read into a Document. From this, we can extract the _description_ of the first _item_:

private String getLatestContent(Document document) throws IOException,
        ParserConfigurationException, SAXException {

    NodeList nodeList = document.getElementsByTagName("item");
    int length = nodeList.getLength();
    if (length > 0) {
        return getDescriptionContent(nodeList.item(0));
    }

    return null;
}

private String getDescriptionContent(Node root) {
    if (root instanceof Element) {
        Element asElement = (Element) root;
        if (asElement.getTagName().equalsIgnoreCase("description")) {
            return asElement.getTextContent();
        }
    }

    NodeList children = root.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        Node node = children.item(i);
        String result = getDescriptionContent(node);
        if (result != null) {
            return result;
        }
    }
    return null;
}


Display the content

Finally, displaying the content is as simple as setting the content of a view! The description of the items from some RSS feeds may contain HTML. For a WebView, the content may be loaded like this:

private void updateView(final String content) {
    final WebView view = (WebView) findViewById(R.id.content);
    view.loadData("<html><body>" + content + "</body></html>",
            "text/html", null);
}

[Java] Specifying the column widths of a JTable as percentages

The widths of the columns of a JTable are specified through TableColumn.setWidth. To set the widths of the columns as percentage, set the widths of column in proportion to each other. For example:

Read more of this post

[Java] Getting Combo Box Renderers to Look Consistent with Other Combo Boxes

One way of controlling the text in a JComboBox is to provide a custom ListCellRenderer. I have seen implementations that subclass a concrete implementation (such as DefaultListCellRenderer or the BasicComboBoxRenderer). Generally though, I find that the combo boxes using such renderers can appear inconsistent with another combo box that may not have a renderer set or one that extends a different implementation. To illustrate the inconsistency that could happen, I prepared a small test program that you can download from my Github repository. It displays a number of combo boxes that are based on different renderers. Just running it produces the following dialog in Windows 7:

Read more of this post

[Android] Using Frame Animation to Recreate the Flashing Arrow

Previously, I wrote about creating a simple animation of a flashing arrow using timers to hide and display a view at regular intervals (see A Simple Way To Make View Flash on Top of Another View). Another way to do this is to use Frame Animation, which is created by displaying a series of frames. Frame animation is actually covered in the Android Dev Guide, under View Animation. Here, using the same steps as described in the guide, the animation of the flashing arrow from the previous post is recreated.

Read more of this post

[Android] A Simple Way To Make View Flash on Top of Another View

[Android] Simple Flashing a View on Top of Another View

Flashing an image is a simple animation that can be achieved by laying an image on top of another and toggling the visibility at regular intervals. In Android, a View can be placed on top of another View, with a FrameLayout. Views can also be hidden and displayed by changing its visibility, through setVisibility. To demonstrate this method, I’ve prepared a small example of an arrow that flashes over a rocket when the rocket is clicked (the rocket and arrow clipart were obtained from Open Clip Art Library). The source is available from my Github repository.

Read more of this post

[KVM] Installing Virtio drivers in a KVM Windows guest VM

KVM provides a Virtio interface for the virtual hard disk and NIC. To use them in a Windows guest VM, the drivers from Fedora (you only need the ISO file) must first be installed into Windows. To install them in a Windows guest VM, it must also be started with these interfaces so that Windows can detect them. While the Windows guest could be started with the Virtio NIC without any problems, we can not start with the Windows image (i.e. the virtual hard disk image where Windows is installed on your guest VM) using the Virtio hard disk interface (until the driver is installed, Windows will not know how to use the Virtio hard disk interface). The easiest solution to this problem is to create another virtual disk that can use Virtio:

qemu-img create -f qcow2 <image name> <size>

Read more of this post

[Python] Creating Custom Cookies for HTTP Requests

One way of adding a custom cookie is to directly specify the "cookie" field in your request header. For example:

 
request.add_header("Cookie", "something=test+1+2+3; source=script")

Here, two cookies are set in the request ("something" and "source"). Notice that the cookies are fully specified in the string, instead of using urllib.urlencode. Another way of adding cookies is to create Cookie objects and add them to your CookieJar. Before sending your request, add the cookies by using add_cookie_header.
Read more of this post

Follow

Get every new post delivered to your Inbox.