Get images from rss feed - android

I'm trying to display the images of rss feed with Android Studio but I don't know how to do this. I can get all the other items but I don't know why I can't get the images. Can you help me please?
This is my Handler:
public class RSSHandler extends DefaultHandler {
final int state_unknown = 0;
final int state_title = 1;
final int state_description = 2;
final int state_link = 3;
final int state_pubdate = 4;
final int state_enclosure = 5;
final int state_url = 6;
int currentState = state_unknown;
RSSFeed feed;
RSSItem item;
boolean itemFound = false;
RSSHandler(){
}
RSSFeed getFeed(){
return feed;
}
#Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
feed = new RSSFeed();
item = new RSSItem();
}
#Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
itemFound = true;
item = new RSSItem();
currentState = state_unknown;
}
else if (localName.equalsIgnoreCase("url")){
currentState = state_url;
}
//{
// if (!attributes.getValue("url").equalsIgnoreCase("null")) {
// feed.setImage(attributes.getValue("url"));
//} else {
// feed.setImage("");
//}
// currentState = state_image;
//}
else if (localName.equalsIgnoreCase("enclosure")){
currentState = state_enclosure;
}
else if (localName.equalsIgnoreCase("title")){
currentState = state_title;
}
else if (localName.equalsIgnoreCase("description")){
currentState = state_description;
}
else if (localName.equalsIgnoreCase("link")){
currentState = state_link;
}
else if (localName.equalsIgnoreCase("pubdate")){
currentState = state_pubdate;
}
else{
currentState = state_unknown;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
feed.addItem(item);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
String strCharacters = new String(ch,start,length);
if (itemFound==true){
// "item" tag found, it's item's parameter
switch(currentState){
case state_url:
item.setUrl(strCharacters);
break;
case state_enclosure:
item.setEnclosure(strCharacters);
break;
case state_title:
item.setTitle(strCharacters);
break;
case state_description:
item.setDescription(strCharacters);
break;
case state_link:
item.setLink(strCharacters);
break;
case state_pubdate:
item.setPubdate(strCharacters);
break;
default:
break;
}
}
else{
// not "item" tag found, it's feed's parameter
switch(currentState){
case state_url:
feed.setUrl(strCharacters);
break;
case state_enclosure:
feed.setEnclosure(strCharacters);
break;
case state_title:
feed.setTitle(strCharacters);
break;
case state_description:
feed.setDescription(strCharacters);
break;
case state_link:
feed.setLink(strCharacters);
break;
case state_pubdate:
feed.setPubdate(strCharacters);
break;
default:
break;
}
}
currentState = state_unknown;
}
EDIT
how I show images
try {
URL url = new URL(web.get(position).getEnclosure()+web.get(position).getUrl());
HttpGet httpRequest;
httpRequest = new HttpGet(url.toURI());
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient
.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity b_entity = new BufferedHttpEntity(entity);
InputStream input = b_entity.getContent();
ImageView img = (ImageView) rowView.findViewById(R.id.enclosure);
Bitmap bitmap = BitmapFactory.decodeStream(input);
img.setImageBitmap(bitmap);
} catch (Exception ex) {
ex.printStackTrace();
}

The code you've posted isn't really relevant to the problem, you should have already fetched the feed and parsed it to extract the urls, you can then do the following, however I would recommend Picasso from Square instead which will do all the heavy lifting AND add functionality like caching and interrupting requests automatically - http://square.github.io/picasso/
try {
InputStream inStream = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(inStream, "my source name");
return d;
} catch (Exception e) {
return null;
}

Related

RSS feed images not shown using AsyncTask

I'm using AsyncTask trying to display the images of the rss feed. I'm catching the url of them from my RSSHandler and I want the images to be shown in my custom ListView but there's nothing. May you help me please? I'm stuck with this.
Yhis is the message in the LogCat:
FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:138)
at com.riccardo.myapplication.DownloadImagesTask.download_Image(DownloadImagesTask.java:42)
at com.riccardo.myapplication.DownloadImagesTask.doInBackground(DownloadImagesTask.java:20)
at com.riccardo.myapplication.DownloadImagesTask.doInBackground(DownloadImagesTask.java:13)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
This is my Handler (edited):
public class RSSHandler extends DefaultHandler {
final int state_unknown = 0;
final int state_title = 1;
final int state_description = 2;
final int state_link = 3;
final int state_pubdate = 4;
int currentState = state_unknown;
ImageView imm;
RSSFeed feed;
RSSItem item;
boolean itemFound = false;
RSSHandler(){
}
RSSFeed getFeed(){
return feed;
}
#Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
feed = new RSSFeed();
item = new RSSItem();
}
#Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
itemFound = true;
item = new RSSItem();
currentState = state_unknown;
}
if ("enclosure".equals(qName)) {
int i;
for (i = 0; i < attributes.getLength(); i++)
if (attributes.getQName(i).equals("url")) ;
String url = attributes.getValue(i);
DownloadImagesTask downloadImages = new DownloadImagesTask(imm);
downloadImages.execute(url);
}
else if (localName.equalsIgnoreCase("title")){
currentState = state_title;
}
else if (localName.equalsIgnoreCase("description")){
currentState = state_description;
}
else if (localName.equalsIgnoreCase("link")){
currentState = state_link;
}
else if (localName.equalsIgnoreCase("pubdate")){
currentState = state_pubdate;
}
else{
currentState = state_unknown;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
feed.addItem(item);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
String strCharacters = new String(ch,start,length);
if (itemFound==true){
// "item" tag found, it's item's parameter
switch(currentState){
case state_title:
item.setTitle(strCharacters);
break;
case state_description:
item.setDescription(strCharacters);
break;
case state_link:
item.setLink(strCharacters);
break;
case state_pubdate:
item.setPubdate(strCharacters);
break;
default:
break;
}
}
else{
// not "item" tag found, it's feed's parameter
switch(currentState){
case state_title:
feed.setTitle(strCharacters);
break;
case state_description:
feed.setDescription(strCharacters);
break;
case state_link:
feed.setLink(strCharacters);
break;
case state_pubdate:
feed.setPubdate(strCharacters);
break;
default:
break;
}
}
currentState = state_unknown;
}
this my AsyncTask (edited):
public class DownloadImagesTask extends AsyncTask<String, Void, Bitmap> {
ImageView imageView = null;
String log = null;
public DownloadImagesTask(ImageView imageView){
//Put logic you need in the constructor
this.imageView = imageView;
}
#Override
protected Bitmap doInBackground(String... Urls) {
return download_Image(Urls[0]);
}
private Bitmap download_Image(String url) {
Bitmap bmp =null;
try{
URL ulrn = new URL(url);
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
return bmp;
}
catch(Exception e){
e.printStackTrace();
Log.d(log, "url= " + url);
}
return bmp;}
#Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
and this my custom ListView (edited):
public class CustomList extends ArrayAdapter<RSSItem> {
private final Activity context;
private final List<RSSItem> web;
private String url;
private AssetManager assets;
public CustomList(Activity context, List<RSSItem> web) {
super(context, R.layout.list_item, web);
this.context = context;
this.web = web;
this.url = url;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
final View rowView = inflater.inflate(R.layout.list_item, null, true);
Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), "BPreplay.otf");
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
final TextView txtTitle = (TextView) rowView.findViewById(R.id.item);
txtTitle.setText(web.get(position).getTitle());
txtTitle.setTypeface(myTypeface);
final TextView txtTitle2 = (TextView) rowView.findViewById(R.id.item2);
txtTitle2.setText(web.get(position).getDescription() + "...");
txtTitle2.setTypeface(myTypeface);
TextView txtTitle3 = (TextView) rowView.findViewById(R.id.pub);
txtTitle3.setText(web.get(position).getPubdate());
txtTitle3.setTypeface(myTypeface);
final TextView txtTitle4 = (TextView) rowView.findViewById(R.id.linke);
txtTitle4.setText("vai all'articolo completo --> " + web.get(position).getLink());
txtTitle4.setTypeface(myTypeface);
Button btn = (Button)rowView.findViewById(R.id.btn_share);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Leggi " +"''" + txtTitle.getText().toString()
+ ": " + txtTitle2.getText().toString()
+ txtTitle4.getText().toString() + "'' " + "Condiviso da Active News");
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, rowView.getResources().getText(R.string.chooser_title)));
}
});
ImageView img = (ImageView)rowView.findViewById(R.id.immagine_feed);
DownloadImagesTask downloadImages = new DownloadImagesTask(img);
downloadImages.execute(url);
return rowView;
}
}
The issue occurs here:
#Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
download_Image takes a url as a string parameter, why are you passing the imageView.getTag();
Change your asyncTask to something like this:
public class DownloadImagesTask extends AsyncTask<String, Void, Bitmap> {
ImageView imageView = null;
public DownloadImagesTask(ImageView imageView){
//Put logic you need in the constructor
this.imageView = imageView;
}
#Override
protected Bitmap doInBackground(String... Urls) {
return download_Image(Urls[0]);
}
#Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}
So when you call it you would pass an imageView to the constructor, then pass a string url to the execute method of the asyntask:
DownloadImagesTask downloadImages = new DownloadImagesTask(someImageView);
downloadImages.execute("http://www.yoururl.com/api/");
EDIT:
Run the task right after you get the both url and imageview.
public CustomList(Activity context, List<RSSItem> web, String url) {
super(context, R.layout.list_item, web);
this.context = context;
this.web = web;
this.url = url;
}
DownloadImagesTask downloadImages = new DownloadImagesTask(img);
downloadImages.execute(url);
make sure you have a url Log.d(log, "url= " + url);

How to decode a string from xml in android?

In my xml, i have <ns5:Name>mil & carbon</ns5:Name>
From my java code i am retrieving that value by
public class MasterdataParser extends MasterdataBaseParser {
protected MasterdataParser(InputStream response) {
super(response);
}
public MasterData parse() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
MasterData masterData;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
Element root = dom.getDocumentElement();
masterData = new MasterData();
NodeList list;
Element element;
NodeList childNodeList;
Node node;
String nodeName;
list = root.getElementsByTagName(PREFIX+CATEGORY);
for (int i=0;i<list.getLength();i++){
element = (Element) list.item(i);
childNodeList = element.getChildNodes();
Category category = new Category();
for (int j = 0; j < childNodeList.getLength(); j++) {
node = childNodeList.item(j);
nodeName = node.getNodeName();
if (nodeName.equalsIgnoreCase(PREFIX+CATEGORY_ID)) {
try{
category.setId(node.getFirstChild().getNodeValue());
} catch (NullPointerException ex) {
category.setId(null);
}
}
if (nodeName.equalsIgnoreCase(PREFIX+CATEGORY_NAME)) {
try{
// System.out.println("Masterdataparser category name html "+Html.fromHtml(node.getFirstChild().getNodeValue())); // Not worked
System.out.println("URL Decoder "+URLDecoder.decode(node.getFirstChild().getNodeValue(), "UTF-8")); // Not worked
category.setName(node.getFirstChild().getNodeValue());
} catch (NullPointerException ex) {
category.setName(null);
}
}
}
public abstract class MasterdataBaseParser implements MasterdataParserInterface {
static final String CATEGORY = "Category";
static final String CATEGORY_ID = "Id";
static final String CATEGORY_NAME = "Name";
final InputStream response;
protected MasterdataBaseParser(InputStream response){
this.response = response;
}
protected InputStream getInputStream() {
return response;
}
}
But it displays only "mil" and it is not taking "&" as "&". But i want to display "mil & carbon". How to do this one? Advance thanks for any help
Here is an example of how i do things with one class parser and several xml stream :
public class RSSHandler extends DefaultHandler {
int RSS_ID;
ContentValues parsedValues = new ContentValues();
private String parsedString = null;
protected DataController _dataController;
private StringBuffer parsedBuffer = new StringBuffer();
public void setRssId(int rssId) {
RSS_ID = rssId;
}
public void setDataController(DataController dataController) {
_dataController = (DataController) dataController;
}
#Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
}
#Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
parsedString = parsedString.trim();
switch (RSS_ID) {
case (0):
if (localName.equals("Application")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (1):
if (localName.equals("tab")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (2):
if (localName.equals("category")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (3):
if (localName.equals("item")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (4):
if (localName.equals("event")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (5):
if (localName.equals("album")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (6):
if (localName.equals("picture")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
case (7):
if (localName.equals("location")) {
_dataController.insertRowInTable(RSS_ID, parsedValues);
}
else {
parsedValues.put(localName, parsedString);
}
break;
default:
break;
}
parsedString = "";
parsedBuffer = new StringBuffer();
}
#Override
public void characters(char ch[], int start, int length) {
parsedBuffer.append(ch, start, start + length);
parsedString = parsedBuffer.toString();
}
}
DataController is just a global class to acces methods and attributes.
public void insertRowInTable(int tableId, ContentValues myRow) {
String myTable = _tableNameList.get(tableId);
_dataBaseHelper.createRowInTable(myTable, myRow);
}
public void createRowInTable(String tableName, ContentValues values) {
try {
myDataBase.insert(tableName, null, values);
}
catch (Exception e) {
//catch
}
}
While parsing xml, by default "&" is behaving as "Escape sequence"(In android lower version like 2.2) that's why i can't able to parse that "mil & carbon". So before parsing, i replaced "&" with "ampersand"(In words) under the file and after fetching that node as "mil ampersand carbon" then replacing the "ampersand" with "&"(symbol). And lots of thanks to "Yume" sir

RSS Reader doesent fetch HTML Characters

The RSS Reader doesent fetch HTML Characters like "#8220;" so when the feed is "Hey#8220;" the App shows only "Hey" but i doesent know why. I tried things like Html.fromHtml, but it doesent work. Does anyone see the mistake?
Thanks for answers
`public class AndroidRssReader extends ListActivity {
private RSSFeed myRssFeed = null;
TextView feedTitle;
TextView feedDescribtion;
TextView feedPubdate;
TextView feedLink;
public class MyCustomAdapter extends ArrayAdapter<RSSItem> {
public MyCustomAdapter(Context context, int textViewResourceId,
List<RSSItem> list) {
super(context, textViewResourceId, list);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
//return super.getView(position, convertView, parent);
View row = convertView;
if(row==null){
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.row, parent, false);
}
TextView listTitle=(TextView)row.findViewById(R.id.listtitle);
listTitle.setText(myRssFeed.getList().get(position).getTitle());
TextView listPubdate=(TextView)row.findViewById(R.id.listpubdate);
listPubdate.setText(myRssFeed.getList().get(position).getPubdate());
if (position%2 == 0){
listTitle.setBackgroundColor(0xff101010);
listPubdate.setBackgroundColor(0xff101010);
}
else{
listTitle.setBackgroundColor(0xff080808);
listPubdate.setBackgroundColor(0xff080808);
}
return row;
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
feedTitle = (TextView)findViewById(R.id.feedtitle);
feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
feedPubdate = (TextView)findViewById(R.id.feedpubdate);
feedLink = (TextView)findViewById(R.id.feedlink);
readRss();
}
private void readRss(){
feedTitle.setText("--- wait ---");
feedDescribtion.setText("");
feedPubdate.setText("");
feedLink.setText("");
setListAdapter(null);
Toast.makeText(this, "News werden geladen...", Toast.LENGTH_LONG).show();
try {
URL rssUrl = new URL("MYURL");
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)
{
Calendar c = Calendar.getInstance();
String strCurrentTiime = "\n(Time of Reading - "
+ c.get(Calendar.HOUR_OF_DAY)
+ " : "
+ c.get(Calendar.MINUTE) + ")\n";
feedTitle.setText(myRssFeed.getTitle() + strCurrentTiime);
feedDescribtion.setText(myRssFeed.getDescription());
feedPubdate.setText(myRssFeed.getPubdate());
feedLink.setText(myRssFeed.getLink());
MyCustomAdapter adapter =
new MyCustomAdapter(this, R.layout.row, 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);*/
Uri feedUri = Uri.parse(myRssFeed.getItem(position).getLink());
Intent myIntent = new Intent(Intent.ACTION_VIEW, feedUri);
startActivity(myIntent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, 0, 0, "Refresh");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()){
case (0): readRss();
break;
default:
break;
}
return true;
}
}`
public class RSSFeed {
private String title = null;
private String description = null;
private String link = null;
private String pubdate = null;
private List<RSSItem> itemList;
RSSFeed(){
itemList = new Vector<RSSItem>(0);
}
void addItem(RSSItem item){
itemList.add(item);
}
RSSItem getItem(int location){
return itemList.get(location);
}
List<RSSItem> getList(){
return itemList;
}
void setTitle(String value)
{
title = value;
}
void setDescription(String value)
{
description = value;
}
void setLink(String value)
{
link = value;
}
void setPubdate(String value)
{
pubdate = value;
}
String getTitle()
{
return title;
}
String getDescription()
{
return description;
}
String getLink()
{
return link;
}
String getPubdate()
{
return pubdate;
}
}
public class RSSHandler extends DefaultHandler {
final int state_unknown = 0;
final int state_title = 1;
final int state_description = 2;
final int state_link = 3;
final int state_pubdate = 4;
int currentState = state_unknown;
RSSFeed feed;
RSSItem item;
boolean itemFound = false;
RSSHandler(){
}
RSSFeed getFeed(){
return feed;
}
#Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
feed = new RSSFeed();
item = new RSSItem();
}
#Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
itemFound = true;
item = new RSSItem();
currentState = state_unknown;
}
else if (localName.equalsIgnoreCase("title")){
currentState = state_title;
}
else if (localName.equalsIgnoreCase("description")){
currentState = state_description;
}
else if (localName.equalsIgnoreCase("link")){
currentState = state_link;
}
else if (localName.equalsIgnoreCase("pubdate")){
currentState = state_pubdate;
}
else{
currentState = state_unknown;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
feed.addItem(item);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
String strCharacters = new String(ch,start,length);
if (itemFound==true){
// "item" tag found, it's item's parameter
switch(currentState){
case state_title:
item.setTitle(strCharacters);
break;
case state_description:
item.setDescription(strCharacters);
break;
case state_link:
item.setLink(strCharacters);
break;
case state_pubdate:
item.setPubdate(strCharacters);
break;
default:
break;
}
}
else{
// not "item" tag found, it's feed's parameter
switch(currentState){
case state_title:
feed.setTitle(strCharacters);
break;
case state_description:
feed.setDescription(strCharacters);
break;
case state_link:
feed.setLink(strCharacters);
break;
case state_pubdate:
feed.setPubdate(strCharacters);
break;
default:
break;
}
}
currentState = state_unknown;
}
}
public class RSSItem {
private String title = null;
private String description = null;
private String link = null;
private String pubdate = null;
RSSItem(){
}
void setTitle(String value)
{
value.replace("#8220;", "hi");
title =value;
}
void setDescription(String value)
{
description = value;
}
void setLink(String value)
{
link = value;
}
void setPubdate(String value)
{
pubdate = value;
}
String getTitle()
{
return title;
}
String getDescription()
{
return description;
}
String getLink()
{
return link;
}
String getPubdate()
{
return pubdate;
}
/*#Override
public String toString() {
// TODO Auto-generated method stub
return title;
}*/
}
InputSource myInputSource = new InputSource(rssUrl.openStream());
myXMLReader.parse(myInputSource);
Set an encoding to your input source or stream. This sample code can help you.

Parsing CDATA in android RSS

I'm trying to make an ANDROID app that reads RSS feeds so I used this tutorial ( http://android-er.blogspot.com/2010/05/simple-rss-reader-ii-implement-with.html ) and implemented it to my own url rss feeder. But the description tag isn't being shown..mostly cz in the xml of the feeder the description tags are CDATA. how can i parse the description cdata in my rss??Thanks!
here is my RSSHandler code :
import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;
public class RSSHandler extends DefaultHandler {
final int state_unknown = 0;
final int state_title = 1;
final int state_description = 2;
final int state_link = 3;
final int state_pubdate = 4;
int currentState = state_unknown;
RSSFeed feed;
RSSItem item;
boolean itemFound = false;
RSSHandler(){
}
RSSFeed getFeed(){
return feed;
}
#Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
feed = new RSSFeed();
item = new RSSItem();
}
#Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
itemFound = true;
item = new RSSItem();
currentState = state_unknown;
}
else if (localName.equalsIgnoreCase("title")){
currentState = state_title;
}
else if (localName.equalsIgnoreCase("description")){
currentState = state_description;
}
else if (localName.equalsIgnoreCase("link")){
currentState = state_link;
}
else if (localName.equalsIgnoreCase("pubdate")){
currentState = state_pubdate;
}
else{
currentState = state_unknown;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("item")){
feed.addItem(item);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
String strCharacters = new String(ch,start,length);
if (itemFound==true){
// "item" tag found, it's item's parameter
switch(currentState){
case state_title:
item.setTitle(strCharacters);
break;
case state_description:
item.setDescription(strCharacters);
break;
case state_link:
item.setLink(strCharacters);
break;
case state_pubdate:
item.setPubdate(strCharacters);
break;
default:
break;
}
}
else{
// not "item" tag found, it's feed's parameter
switch(currentState){
case state_title:
feed.setTitle(strCharacters);
break;
case state_description:
feed.setDescription(strCharacters);
break;
case state_link:
feed.setLink(strCharacters);
break;
case state_pubdate:
feed.setPubdate(strCharacters);
break;
default:
break;
}
}
currentState = state_unknown;
}
and here is my RSSReader code :
public class AndroidRssReader extends ListActivity {
private RSSFeed myRssFeed = null;
//private ArrayList<RSSItem> 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");
URL rssUrl = new URL("http://www.merehbi.com/online/index.php?option=com_content&view=category&layout=blog&id=58&Itemid=155&lang=ar&format=feed&type=rss");
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) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
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) {
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);
}
}
i use this tutorial and its codes
http://www.androidhive.info/2011/11/android-xml-parsing-tutorial/
and change some code by this answer
https://stackoverflow.com/a/8489223/3636653
public static void main(String[] args) throws Exception {
File file = new File("data.xml");
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(file);
NodeList nodes = doc.getElementsByTagName("topic");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList title = element.getElementsByTagName("title");
Element line = (Element) title.item(0);
System.out.println("Title: " + getCharacterDataFromElement(line));
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "";
}

Parsing an RSS feed cuts of characters

I parse some RSS feed (tried with different ones...) and everytime pretty randomly characters get cut of.
What am I doing wrong? Why does it work in some instances and in other ones it doesn't?
Is there another way of doing it? The XML will (in most of the cases) include UTF-8 characters (like ä,ö,ü etc.) so the solution should work with those characters too.
If you need any more information (More code, more detailed information etc.) please let me know!
Here is my Code:
public class RSSHandler extends DefaultHandler {
final int state_unknown = 0;
final int state_title = 1;
final int state_description = 2;
final int state_link = 3;
final int state_pubdate = 4;
int currentState = state_unknown;
StringBuilder strCharacters;
RSSFeed feed;
RSSItem item;
boolean inEntity = false;
String entityName = "";
boolean itemFound = false;
public RSSHandler() {
strCharacters = new StringBuilder();
}
public RSSFeed getFeed() {
return feed;
}
#Override
public void startDocument() throws SAXException {
feed = new RSSFeed();
item = new RSSItem();
}
#Override
public void endDocument() throws SAXException {
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
strCharacters = new StringBuilder();
if (localName.equalsIgnoreCase("item")) {
itemFound = true;
item = new RSSItem();
currentState = state_unknown;
} else if (localName.equalsIgnoreCase("title")) {
currentState = state_title;
} else if (localName.equalsIgnoreCase("description")) {
currentState = state_description;
} else if (localName.equalsIgnoreCase("link")) {
currentState = state_link;
} else if (localName.equalsIgnoreCase("pubdate")) {
currentState = state_pubdate;
} else {
currentState = state_unknown;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (itemFound == true) {
switch (currentState) {
case state_title:
item.setTitle(strCharacters.toString());
break;
case state_description:
break;
case state_link:
item.setLink(strCharacters.toString());
break;
case state_pubdate:
String dateStr = strCharacters.toString();
SimpleDateFormat curFormater = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
Date dateObj = null;
try {
dateObj = curFormater.parse(dateStr);
SimpleDateFormat postFormater = new SimpleDateFormat(
"dd.MM.yyyy HH:mm");
String newDateStr = postFormater.format(dateObj);
item.setPubdate(newDateStr);
} catch (ParseException e) {
e.printStackTrace();
}
break;
default:
break;
}
} else {
switch (currentState) {
case state_title:
feed.setTitle(strCharacters.toString());
break;
case state_description:
break;
case state_link:
feed.setLink(strCharacters.toString());
break;
case state_pubdate:
feed.setPubdate(strCharacters.toString());
break;
default:
break;
}
}
currentState = state_unknown;
if (localName.equalsIgnoreCase("item")) {
feed.addItem(item);
}
}
public void startEntity(String name) throws SAXException {
inEntity = true;
entityName = name;
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
strCharacters = new StringBuilder();
if (inEntity) {
inEntity = false;
strCharacters.append("&" + entityName + ";");
} else {
for (int i = start; i < start + length; i++) {
strCharacters.append(ch[i]);
}
}
// strCharacters.append(ch, start, length);
}
}
You are creating a new StringBuilder on each characters() call. This is incorrect. There many be several calls to characters() per element -- you need to concatenate all those results, not just collect the last piece.

Categories

Resources