Monday, May 10, 2010

A simple RSS reader III, show details once item clicked.

Last article "A simple RSS reader II, implement with RSSFeed & RSSItem", only the titles shown in a List. Here, we are going to start another activity to show the details once any item in the list clicked.

A simple RSS reader III, show details once item clicked.

Most of the works from the last article "A simple RSS reader II, implement with RSSFeed & RSSItem", with the changes lsited below.

Implement /res/layout/details.xml, it's the layout of the activity ShowDetails.java
<?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"
  >
<TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="RSS Details:-" />
<TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:id="@+id/detailstitle" />
<TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:id="@+id/detailsdescription" />
<TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:autoLink="web"
  android:id="@+id/detailslink" />
<TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:id="@+id/detailspubdate" />
</LinearLayout>


Implement a new Activity /src/com.exercise.AndroidRssReader/ShowDetails.java, it will be started once any item in the list clicked.
package com.exercise.AndroidRssReader;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class ShowDetails extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.details);
 TextView detailsTitle = (TextView)findViewById(R.id.detailstitle);
 TextView detailsDescription = (TextView)findViewById(R.id.detailsdescription);
 TextView detailsPubdate = (TextView)findViewById(R.id.detailspubdate);
 TextView detailsLink = (TextView)findViewById(R.id.detailslink);

 Bundle bundle = this.getIntent().getExtras();
    
      detailsTitle.setText(bundle.getString("keyTitle"));
      detailsDescription.setText(bundle.getString("keyDescription"));
      detailsPubdate.setText(bundle.getString("keyPubdate"));
      detailsLink.setText(bundle.getString("keyLink"));
    
}
}


Modify /src/com.exercise.AndroidRssReader/AndroidRssReader.java to start new activity once any list item clicked.
package com.exercise.AndroidRssReader;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class AndroidRssReader extends ListActivity {

private RSSFeed myRssFeed = null;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
    
      try {
  URL rssUrl = new URL("http://www.gov.hk/en/about/rss/govhkrss.data.xml");
  SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
  SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
  XMLReader myXMLReader = mySAXParser.getXMLReader();
  RSSHandler myRSSHandler = new RSSHandler();
  myXMLReader.setContentHandler(myRSSHandler);
  InputSource myInputSource = new InputSource(rssUrl.openStream());
  myXMLReader.parse(myInputSource);
 
  myRssFeed = myRSSHandler.getFeed();
 
 } catch (MalformedURLException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (ParserConfigurationException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (SAXException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }

 if (myRssFeed!=null)
 {
  TextView feedTitle = (TextView)findViewById(R.id.feedtitle);
  TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
  TextView feedPubdate = (TextView)findViewById(R.id.feedpubdate);
  TextView feedLink = (TextView)findViewById(R.id.feedlink);
  feedTitle.setText(myRssFeed.getTitle());
  feedDescribtion.setText(myRssFeed.getDescription());
  feedPubdate.setText(myRssFeed.getPubdate());
  feedLink.setText(myRssFeed.getLink());
 
  ArrayAdapter<RSSItem> adapter =
   new ArrayAdapter<RSSItem>(this,
     android.R.layout.simple_list_item_1,myRssFeed.getList());
  setListAdapter(adapter);
 
 }
  }

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
 // TODO Auto-generated method stub
 Intent intent = new Intent(this,ShowDetails.class);
 Bundle bundle = new Bundle();
 bundle.putString("keyTitle", myRssFeed.getItem(position).getTitle());
 bundle.putString("keyDescription", myRssFeed.getItem(position).getDescription());
 bundle.putString("keyLink", myRssFeed.getItem(position).getLink());
 bundle.putString("keyPubdate", myRssFeed.getItem(position).getPubdate());
 intent.putExtras(bundle);
      startActivity(intent);
}
}


Modify AndroidManifest.xml to include the new activity.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exercise.AndroidRssReader"
    android:versionCode="1"
    android:versionName="1.0">
  <application android:icon="@drawable/icon" android:label="@string/app_name">
      <activity android:name=".AndroidRssReader"
                android:label="@string/app_name">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>
 <activity android:name=".ShowDetails"></activity>
  </application>
  <uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>


Download the files.

next:
- Apply custom adapter to ListView for RSS Reader
- A simple RSS reader IV, start browser to open the selected feed



25 comments:

  1. Hi,

    Thanks for this series, im just learning how to wirte apps for android so will keep an eye out here. one thing though, is it possible you could upload the full package source for the latest version of the rss reader because i seem to be losing it somewhere in betwwen versions and cant seem to get it working. Many thanks.

    Chris

    ReplyDelete
  2. Ok, I think im learning, ive got it working now, the only two things are dashes in feed item titles break the title so for example:

    Hello - How are You

    Shows as:

    Hello

    and also, is there a way you could show us how to implement a refresh option menu.

    Many Thanks

    Chris

    ReplyDelete
  3. Code is broken, many messages get truncated when used on a phone with a 3G connection.

    Seems to work OK in the emulator.

    ANy ideas on how to fix this?

    ReplyDelete
  4. The code broken may be dur to the returned characters in HTML format. In this exercise, I just handle it as simple String, so it break in HTML such as <, >, >...

    ReplyDelete
  5. Hey this is perfect... Thanks for the tute.
    I'm having one problem though. Because my site doesnt have "clean urls" it has a problem. It gets the feed perfectly but the link from the "showdetails" page gets stuffed up.
    The URLs have the "&" symbol between values passed to the server (i.e /index.php?value1=arg1$value2=arg2)

    So the url gets cut from the "&" and, when I click on the link I end up at list of 4 year old posts.

    I was wondering f there was any way to pass the exception...

    Thanks

    ReplyDelete
  6. So how to make it read the full content texts

    ReplyDelete
  7. Nice tutorial, but I'm also having the issue where the description in the xml is not being read, and simply showing "<". Any idea how this can be resolved?

    ReplyDelete
  8. Hey.
    I am also facing same problem and this is due to the HTML tags or Rich text present in description.
    Can anyone tell me how to read HTML tags or Rich Text in description..

    Thanx in advance.

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Hi! I am following your tutorial and found a issue.

    I'm trying to show the post author name that is on a dc:creator tag.

    IN RSSHamfler.java, I added final int state_author = 5 at class declaration and followed the logic. But isn't working! What do I do?

    Thank you in advice.

    ReplyDelete
  11. Hi, really nice tutarial.
    I try to make custom listview for news list with image and title. How can develop adapter for your code. Thanks,

    Oguz

    ReplyDelete
  12. Hi, thanks for the tutorial. But the problem is that I can't use all of the rss feeds. What seems to be the problem with that??????

    ReplyDelete
  13. I've got the same problem as "Ramblings of a young man"

    Does anybody have a solution?

    ReplyDelete
  14. I've got the same problem as "Ramblings of a young man"

    Does anybody have a solution?

    ReplyDelete
  15. when i click the news feed. it shows error. "application failed"

    whats wrong???

    ReplyDelete
  16. Hi Andr.oid Eric..
    thank you.

    Also i am having problem here.




    android:text="@string/hello_world"

    if i put other than "hello_world" 'waiting' or 'no data'. i am getting error

    error: Error: No resource found that matches the given name (at 'text' with value '@string/
    waiting').

    ReplyDelete
  17. hello Rajkumar Arumugam,

    - you can insert the text directly as:
    android:text="waiting"

    - If you insist to use format of "@string/waiting", you have to edit /res/values/strings.xml file to add resource of the string.

    ReplyDelete
  18. Rajkumar ArumugamMay 1, 2013 at 10:41 PM

    Hi Andr.oid Eric..
    ok. thank you!

    ReplyDelete
  19. Rajkumar ArumugamMay 1, 2013 at 11:42 PM

    Hi Andr.oid Eric..

    for android.os.NetworkOnMainThreadException.
    if i set android:minSdkVersion="8" will it work???


    ReplyDelete
  20. I suppose it's YES. At that time I tested it.

    ReplyDelete
  21. Rajkumar ArumugamMay 6, 2013 at 9:23 PM

    How to open a website in a mobile format automatically?

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    WebView theWebPage = new WebView(this);
    setContentView(theWebPage);
    theWebPage.loadUrl("http://hnauae.com/");
    }

    this code opens a website in a normal view only. how to open the site in mobile format.


    ReplyDelete
  22. hello Rajkumar Arumugam,

    Please read Set ViewPort of WebView.

    But I have tried to load your site with default setting, it already displayed in mobile view.

    ReplyDelete
  23. Hi Andr.oid Eric,

    when we open the rss feed items, its opens out side the app. how to open the contents inside the app?

    also i want to know how to add share button for each rss feed item. i want to place the share button after rss feed item is opened. ?

    ReplyDelete