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:

Unknown said...

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

Unknown said...

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

MMMMMM said...

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?

Erik said...

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 <, >, >...

Dsve said...

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

souliyo said...

So how to make it read the full content texts

Azazel11 said...

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?

Rishabh said...

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.

Rishabh said...
This comment has been removed by the author.
Anonymous said...

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.

Anonymous said...

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

Erik said...

hello Okansoy,

Please refer: ListView with icon loaded from internet.

Oliver Parletić said...

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??????

Rick-B said...

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

Does anybody have a solution?

Rick-B said...

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

Does anybody have a solution?

Unknown said...

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

whats wrong???

Erik said...

hello Rajkumar Arumugam,

May be because of android.os.NetworkOnMainThreadException.

Please read RSS feed reader run in AsyncTask.

Rajkumar Arumugam said...

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').

Erik said...

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.

Rajkumar Arumugam said...

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

Rajkumar Arumugam said...

Hi Andr.oid Eric..

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


Erik said...

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

Rajkumar Arumugam said...

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.


Erik said...

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.

Rajkumar Arumugam said...

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. ?