I am new to programming so please go easy on me, I have been messing around with a simple RSS Reader, trying to get the link to the artice to open in a webview when the user clicks on the article.
I have found the string that controls and stores the link but when I try to print the link in the toast the link appears but with the whole article publishing date ect... how can I get the link to print on it own and what commands do I need to use to pass the link to the webview once I have isolated it, here is some of the code I have
RSSActivity
public class RssActivity extends ListActivity {
private RssListAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<JSONObject> jobs = new ArrayList<JSONObject>();
try {
jobs = RssReader.getLatestRssFeed();
} catch (Exception e) {
Log.e("RSS ERROR", "Error loading RSS Feed Stream >> " + e.getMessage() + " //" + e.toString());
}
adapter = new RssListAdapter(this,jobs);
setListAdapter(adapter);
}
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
Object o = this.getListAdapter().getItem(position);
adapter.getItem(position).toString();
String link = o.toString();
Toast.makeText(this, "You selected: " + link, Toast.LENGTH_LONG)
.show();
}
}
Article.class
public class Article {
private long articleId;
private long feedId;
private String title;
private String description;
private String pubDate;
private URL url;
private String encodedContent;
private String link;
public void setArticleId(long articleId) {
this.articleId = articleId;
}
/**
* #return the feedId
*/
public long getFeedId() {
return feedId;
}
/**
* #param feedId the feedId to set
*/
public void setFeedId(long feedId) {
this.feedId = feedId;
}
public String getLink() {
return link;
}
/**
* #param title the title to set
*/
public void setLink(String link) {
this.link = link;
}
/**
* #return the title
*/
public String getTitle() {
return title;
}
/**
* #param title the title to set
*/
public void setTitle(String title) {
this.title = title;
}
/**
* #return the url
*/
public URL getUrl() {
return url;
}
/**
* #param url the url to set
*/
public void setUrl(URL url) {
this.url = url;
}
/**
* #param description the description to set
*/
public void setDescription(String description) {
this.description = description;
//parse description for any image or video links
if (description.contains("<img ")){
String img = description.substring(description.indexOf("<img "));
String cleanUp = img.substring(0, img.indexOf(">")+1);
int indexOf = img.indexOf("'");
if (indexOf==-1){
}
this.description = this.description.replace(cleanUp, "");
}
}
/**
* #return the description
*/
public String getDescription() {
return description;
}
/**
* #param pubDate the pubDate to set
*/
public void setPubDate(String pubDate) {
this.pubDate = pubDate;
}
/**
* #return the pubDate
*/
public String getPubDate() {
return pubDate;
}
/**
* #param encodedContent the encodedContent to set
*/
public void setEncodedContent(String encodedContent) {
this.encodedContent = encodedContent;
}
/**
* #return the encodedContent
*/
public String getEncodedContent() {
return encodedContent;
}
}
RSS Handler
public class RSSHandler extends DefaultHandler {
// Feed and Article objects to use for temporary storage
private Article currentArticle = new Article();
private List<Article> articleList = new ArrayList<Article>();
// Number of articles added so far
private int articlesAdded = 0;
// Number of articles to download
private static final int ARTICLES_LIMIT = 15;
//Current characters being accumulated
StringBuffer chars = new StringBuffer();
public void startElement(String uri, String localName, String qName, Attributes atts) {
chars = new StringBuffer();
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equalsIgnoreCase("title"))
{
Log.d("LOGGING RSS XML", "Setting article title: " + chars.toString());
currentArticle.setTitle(chars.toString());
}
else if (localName.equalsIgnoreCase("description"))
{
Log.d("LOGGING RSS XML", "Setting article description: " + chars.toString());
currentArticle.setDescription(chars.toString());
}
else if (localName.equalsIgnoreCase("pubDate"))
{
Log.d("LOGGING RSS XML", "Setting article published date: " + chars.toString());
currentArticle.setPubDate(chars.toString());
}
else if (localName.equalsIgnoreCase("encoded"))
{
Log.d("LOGGING RSS XML", "Setting article content: " + chars.toString());
currentArticle.setEncodedContent(chars.toString());
}
else if (localName.equalsIgnoreCase("item"))
{
}
else if (localName.equalsIgnoreCase("link"))
{
Log.d("LOGGING RSS XML", "Setting article link: " + chars.toString());
currentArticle.setLink(chars.toString());
try {
Log.d("LOGGING RSS XML", "Setting article link url: " + chars.toString());
currentArticle.setUrl(new URL(chars.toString()));
} catch (MalformedURLException e) {
Log.e("RSA Error", e.getMessage());
}
}
// Check if looking for article, and if article is complete
if (localName.equalsIgnoreCase("item")) {
articleList.add(currentArticle);
currentArticle = new Article();
// Lets check if we've hit our limit on number of articles
articlesAdded++;
if (articlesAdded >= ARTICLES_LIMIT)
{
throw new SAXException();
}
}
}
public void characters(char ch[], int start, int length) {
chars.append(new String(ch, start, length));
}
public List<Article> getLatestArticles(String feedUrl) {
URL url = null;
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
url = new URL(feedUrl);
xr.setContentHandler(this);
xr.parse(new InputSource(url.openStream()));
} catch (IOException e) {
Log.e("RSS Handler IO", e.getMessage() + " >> " + e.toString());
} catch (SAXException e) {
Log.e("RSS Handler SAX", e.toString());
} catch (ParserConfigurationException e) {
Log.e("RSS Handler Parser Config", e.toString());
}
return articleList;
}
}
public class RssReader {
private final static String BOLD_OPEN = "<B>";
private final static String BOLD_CLOSE = "</B>";
private final static String BREAK = "<BR>";
private final static String ITALIC_OPEN = "<I>";
private final static String ITALIC_CLOSE = "</I>";
private final static String SMALL_OPEN = "<SMALL>";
private final static String SMALL_CLOSE = "</SMALL>";
private final static String WEB_LINK = "<A>";
private final static String WEB_CLOSE = "<A/";
public static List<JSONObject> getLatestRssFeed(){
String feed = "http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/eng_prem/rss.xml";
RSSHandler rh = new RSSHandler();
List<Article> articles = rh.getLatestArticles(feed);
Log.e("RSS ERROR", "Number of articles " + articles.size());
return fillData(articles);
}
private static List<JSONObject> fillData(List<Article> articles) {
List<JSONObject> items = new ArrayList<JSONObject>();
for (Article article : articles) {
JSONObject current = new JSONObject();
try {
buildJsonObject(article, current);
} catch (JSONException e) {
Log.e("RSS ERROR", "Error creating JSON Object from RSS feed");
}
items.add(current);
}
return items;
}
private static void buildJsonObject(Article article, JSONObject current) throws JSONException {
String link = article.getLink();
String title = article.getTitle();
String description = article.getDescription();
String date = article.getPubDate();
StringBuffer sb = new StringBuffer();
sb.append(BOLD_OPEN).append(title).append(BOLD_CLOSE);
sb.append(BREAK);
sb.append(description);
sb.append(BREAK);
sb.append(SMALL_OPEN).append(ITALIC_OPEN).append(date).append(ITALIC_CLOSE).append(SMALL_CLOSE);
sb.append(BREAK);
sb.append(BREAK);
sb.append(BOLD_OPEN).append(WEB_LINK).append(link).append(BOLD_CLOSE).append(WEB_CLOSE);
current.put("link", link);
current.put("text", Html.fromHtml(sb.toString()));
}
}
RssListAdapter
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class RssListAdapter extends ArrayAdapter<JSONObject> {
public RssListAdapter(Activity activity, List<JSONObject> imageAndTexts) {
super(activity, 0, imageAndTexts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Activity activity = (Activity) getContext();
LayoutInflater inflater = activity.getLayoutInflater();
// Inflate the views from XML
View rowView = inflater.inflate(R.layout.image_text_layout, null);
JSONObject jsonImageText = getItem(position);
//////////////////////////////////////////////////////////////////////////////////////////////////////
//The next section we update at runtime the text - as provided by the JSON from our REST call
////////////////////////////////////////////////////////////////////////////////////////////////////
TextView textView = (TextView) rowView.findViewById(R.id.job_text);
try {
Spanned text = (Spanned)jsonImageText.get("text");
textView.setText(text);
} catch (JSONException e) {
textView.setText("JSON Exception");
}
return rowView;
}
}
Open URL in default browser
Open URL with Android
If you have the URL or URI object at one point, probably one of the explanations in the links above will get you on your way.
--
Edit:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
Object o = this.getListAdapter().getItem(position);
adapter.getItem(position).toString();
String link = o.toString();
Toast.makeText(this, "You selected: " + link, Toast.LENGTH_LONG)
.show();
}
Guessing this is the code to show the link but if you don't supply us what the getListAdapter() method etc do then I'm afraid it's hard to help you out.
Try this
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
JSONObject o = (JSONObject) this.getListAdapter().getItem(position);
adapter.getItem(position).toString();
String link = o.getString("NameOfLinkInJsonObject");
Toast.makeText(this, "You selected: " + link, Toast.LENGTH_LONG)
.show();
mMyWebView.loadUrl(link);
}
Be aware that you need to fix "NameOfLinkInJsonObject".
In your activity add a field like so
private WebView mMyWebView;
In your onCreate method add a
mMyWebView = (WebView) findViewById(R.id.webViewId);
You will have to change the R.id.webViewId to the appropriate id for your web view.
Related
My code looks like this:
package com.example.humspots.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.amplifyframework.AmplifyException;
import com.amplifyframework.api.aws.AWSApiPlugin;
import com.amplifyframework.api.graphql.model.ModelMutation;
import com.amplifyframework.api.graphql.model.ModelQuery;
import com.amplifyframework.core.Amplify;
import com.amplifyframework.datastore.generated.model.Event;
import com.example.humspots.R;
import com.example.humspots.adapters.EventAdapter;
import java.util.ArrayList;
import java.util.List;
import static com.parse.Parse.getApplicationContext;
/**
* A simple {#link Fragment} subclass.
*/
public class EventsFragment extends Fragment {
public static final String EVENTBRITE_URL = "https://www.eventbriteapi.com/v3/users/me/?token=FXZ47VT64UDMVS6KNOP4";
public static final String HSU_URL = "https://25livepub.collegenet.com/calendars/student-project-humboldt-app.json";
public static final String ORGANIZATION_URL = "https://www.eventbriteapi.com/v3/organizations/436148186604/events/?token=FXZ47VT64UDMVS6KNOP4";
public static final String TAG = "EventsFragment";
EventAdapter eventAdapter;
List<Event> events;
RecyclerView rvEvents;
public EventsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_events, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
rvEvents = view.findViewById(R.id.rvEvents);
//bottomNavigationView = findViewById(R.id.bottomNavigation);
events = new ArrayList<>();
amplifyAndSetAdapter();
eventAdapter.notifyDataSetChanged();
}
private void addEventToAWS() {
Event todo = Event.builder().eventTitle("My todo")
.eventDate("11/21/20")
.eventTime("11:30:00")
.extraInfo("AHHHHHHHHHHHHHHHHH")
.category("temp")
.description("this is a description")
.template("Lost Coast")
.postUrl("https://docs.amplify.aws/lib/graphqlapi/mutate-data/q/platform/android")
.venue("McDonalds")
.build();
Amplify.API.mutate(
ModelMutation.create(todo),
response -> Log.i(TAG, "Added Todo with id: " + response.getData().getId()),
error -> Log.e(TAG, "Create failed", error)
);
}
private void amplifyAndSetAdapter() {
initializeAmplify();
amplifyQuery();
}
private void initializeAmplify() {
try {
// Add these lines to add the AWSApiPlugin plugins
Amplify.addPlugin(new AWSApiPlugin());
Amplify.configure(getApplicationContext());
Log.i(TAG, "Initialized Amplify");
} catch (AmplifyException error) {
Log.e(TAG, "Could not initialize Amplify", error);
}
}
private void amplifyQuery() {
//create the adapter
eventAdapter = new EventAdapter(getContext(), events);
//set a layout manager on RV
rvEvents.setLayoutManager(new LinearLayoutManager(getContext()));
//set the adapter on the recycler view
rvEvents.setAdapter(eventAdapter);
Amplify.API.query(
ModelQuery.list(Event.class),
response -> {
for (Event event : response.getData()) {
Log.i("Amplify", event.getEventTitle() + " " + event.getEventDate() + " " + event.getEventTime() + " " + event.getCategory()
+ " " + event.getPostUrl() + " " + event.getExtraInfo() + " " + event.getVenue() + " " + event.getTemplate());
addEvents(event);
}
},
error -> Log.e("Amplify", "Query failure", error)
);
}
private void addEvents(Event event) {
try {
events.add(event);
Log.i(TAG, "Events: " + events.size());
} catch (Exception e) {
Log.e(TAG, "Events: ", e);
}
}
}
the EventAdapter looks like this:
package com.example.humspots.adapters;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amplifyframework.datastore.generated.model.Event;
import com.bumptech.glide.Glide;
import com.example.humspots.DetailActivity;
import com.example.humspots.R;
import org.parceler.Parcels;
import java.util.List;
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.ViewHolder> {
Context context;
List<Event> events;
public EventAdapter(Context context, List<Event> events) {
this.context = context;
this.events = events;
}
//usually involves inflating a layout from XML and returning the viewholder
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View eventView = LayoutInflater.from(context).inflate(R.layout.item_event, parent, false);
return new ViewHolder(eventView);
}
//involves populating data into the item through holder
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//get the event at the given position
Event event = events.get(position);
//bind the event data into the view holder
holder.bind(event);
}
//returns the total number of items in the list
#Override
public int getItemCount() {
return events.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
RelativeLayout container;
TextView tvDay;
TextView tvMonth;
TextView tvEventTitle;
TextView tvSummary;
ImageView ivEventImage;
public ViewHolder(#NonNull View itemView) {
super(itemView);
container = itemView.findViewById(R.id.Container);
tvDay = itemView.findViewById(R.id.tvDay);
tvMonth = itemView.findViewById(R.id.tvMonth);
tvEventTitle = itemView.findViewById(R.id.tvEventTitle);
tvSummary = itemView.findViewById(R.id.tvSummary);
ivEventImage = itemView.findViewById(R.id.ivEventImage);
}
public void bind(final Event event) {
tvDay.setText(event.getDayOfMonth());
tvMonth.setText(event.getMonthOfYear());
tvEventTitle.setText(event.getEventTitle());
tvSummary.setText(event.getDescription());
//Glide.with(context).load(event.getPostUrl()).into(ivEventImage);
//register the click listener on the whole container.
container.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//then, navigate to new activity on click.
Intent i = new Intent(context, DetailActivity.class);
i.putExtra("event", Parcels.wrap(event));
context.startActivity(i);
}
});
}
}
}
event looks like this:
package com.amplifyframework.datastore.generated.model;
import java.util.List;
import java.util.UUID;
import java.util.Objects;
import androidx.core.util.ObjectsCompat;
import com.amplifyframework.core.model.Model;
import com.amplifyframework.core.model.annotations.Index;
import com.amplifyframework.core.model.annotations.ModelConfig;
import com.amplifyframework.core.model.annotations.ModelField;
import com.amplifyframework.core.model.query.predicate.QueryField;
import static com.amplifyframework.core.model.query.predicate.QueryField.field;
/** This is an auto generated class representing the Event type in your schema. */
#SuppressWarnings("all")
#ModelConfig(pluralName = "Events")
public final class Event implements Model {
public static final QueryField ID = field("id");
public static final QueryField EVENT_TITLE = field("EventTitle");
public static final QueryField DESCRIPTION = field("Description");
public static final QueryField EVENT_DATE = field("EventDate");
public static final QueryField EVENT_TIME = field("EventTime");
public static final QueryField CATEGORY = field("Category");
public static final QueryField POST_URL = field("PostURL");
public static final QueryField EXTRA_INFO = field("ExtraInfo");
public static final QueryField VENUE = field("Venue");
public static final QueryField TEMPLATE = field("Template");
private final #ModelField(targetType="ID", isRequired = true) String id;
private final #ModelField(targetType="String") String EventTitle;
private final #ModelField(targetType="String") String Description;
private final #ModelField(targetType="String") String EventDate;
private final #ModelField(targetType="String") String EventTime;
private final #ModelField(targetType="String") String Category;
private final #ModelField(targetType="String") String PostURL;
private final #ModelField(targetType="String") String ExtraInfo;
private final #ModelField(targetType="String") String Venue;
private final #ModelField(targetType="String") String Template;
public String getId() {
return id;
}
public String getEventTitle() {
return EventTitle;
}
public String getDescription() {
return Description;
}
public String getEventDate() {
return EventDate;
}
public String getEventTime() {
return EventTime;
}
public String getCategory() {
return Category;
}
public String getPostUrl() {
return PostURL;
}
public String getExtraInfo() {
return ExtraInfo;
}
public String getVenue() {
return Venue;
}
public String getTemplate() {
return Template;
}
private Event(String id, String EventTitle, String Description, String EventDate, String EventTime, String Category, String PostURL, String ExtraInfo, String Venue, String Template) {
this.id = id;
this.EventTitle = EventTitle;
this.Description = Description;
this.EventDate = EventDate;
this.EventTime = EventTime;
this.Category = Category;
this.PostURL = PostURL;
this.ExtraInfo = ExtraInfo;
this.Venue = Venue;
this.Template = Template;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if(obj == null || getClass() != obj.getClass()) {
return false;
} else {
Event event = (Event) obj;
return ObjectsCompat.equals(getId(), event.getId()) &&
ObjectsCompat.equals(getEventTitle(), event.getEventTitle()) &&
ObjectsCompat.equals(getDescription(), event.getDescription()) &&
ObjectsCompat.equals(getEventDate(), event.getEventDate()) &&
ObjectsCompat.equals(getEventTime(), event.getEventTime()) &&
ObjectsCompat.equals(getCategory(), event.getCategory()) &&
ObjectsCompat.equals(getPostUrl(), event.getPostUrl()) &&
ObjectsCompat.equals(getExtraInfo(), event.getExtraInfo()) &&
ObjectsCompat.equals(getVenue(), event.getVenue()) &&
ObjectsCompat.equals(getTemplate(), event.getTemplate());
}
}
#Override
public int hashCode() {
return new StringBuilder()
.append(getId())
.append(getEventTitle())
.append(getDescription())
.append(getEventDate())
.append(getEventTime())
.append(getCategory())
.append(getPostUrl())
.append(getExtraInfo())
.append(getVenue())
.append(getTemplate())
.toString()
.hashCode();
}
#Override
public String toString() {
return new StringBuilder()
.append("Event {")
.append("id=" + String.valueOf(getId()) + ", ")
.append("EventTitle=" + String.valueOf(getEventTitle()) + ", ")
.append("Description=" + String.valueOf(getDescription()) + ", ")
.append("EventDate=" + String.valueOf(getEventDate()) + ", ")
.append("EventTime=" + String.valueOf(getEventTime()) + ", ")
.append("Category=" + String.valueOf(getCategory()) + ", ")
.append("PostURL=" + String.valueOf(getPostUrl()) + ", ")
.append("ExtraInfo=" + String.valueOf(getExtraInfo()) + ", ")
.append("Venue=" + String.valueOf(getVenue()) + ", ")
.append("Template=" + String.valueOf(getTemplate()))
.append("}")
.toString();
}
public static BuildStep builder() {
return new Builder();
}
/**
* WARNING: This method should not be used to build an instance of this object for a CREATE mutation.
* This is a convenience method to return an instance of the object with only its ID populated
* to be used in the context of a parameter in a delete mutation or referencing a foreign key
* in a relationship.
* #param id the id of the existing item this instance will represent
* #return an instance of this model with only ID populated
* #throws IllegalArgumentException Checks that ID is in the proper format
*/
public static Event justId(String id) {
try {
UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
} catch (Exception exception) {
throw new IllegalArgumentException(
"Model IDs must be unique in the format of UUID. This method is for creating instances " +
"of an existing object with only its ID field for sending as a mutation parameter. When " +
"creating a new object, use the standard builder method and leave the ID field blank."
);
}
return new Event(
id,
null,
null,
null,
null,
null,
null,
null,
null,
null
);
}
public CopyOfBuilder copyOfBuilder() {
return new CopyOfBuilder(id,
EventTitle,
Description,
EventDate,
EventTime,
Category,
PostURL,
ExtraInfo,
Venue,
Template);
}
public interface BuildStep {
Event build();
BuildStep id(String id) throws IllegalArgumentException;
BuildStep eventTitle(String eventTitle);
BuildStep description(String description);
BuildStep eventDate(String eventDate);
BuildStep eventTime(String eventTime);
BuildStep category(String category);
BuildStep postUrl(String postUrl);
BuildStep extraInfo(String extraInfo);
BuildStep venue(String venue);
BuildStep template(String template);
}
public static class Builder implements BuildStep {
private String id;
private String EventTitle;
private String Description;
private String EventDate;
private String EventTime;
private String Category;
private String PostURL;
private String ExtraInfo;
private String Venue;
private String Template;
#Override
public Event build() {
String id = this.id != null ? this.id : UUID.randomUUID().toString();
return new Event(
id,
EventTitle,
Description,
EventDate,
EventTime,
Category,
PostURL,
ExtraInfo,
Venue,
Template);
}
#Override
public BuildStep eventTitle(String eventTitle) {
this.EventTitle = eventTitle;
return this;
}
#Override
public BuildStep description(String description) {
this.Description = description;
return this;
}
#Override
public BuildStep eventDate(String eventDate) {
this.EventDate = eventDate;
return this;
}
#Override
public BuildStep eventTime(String eventTime) {
this.EventTime = eventTime;
return this;
}
#Override
public BuildStep category(String category) {
this.Category = category;
return this;
}
#Override
public BuildStep postUrl(String postUrl) {
this.PostURL = postUrl;
return this;
}
#Override
public BuildStep extraInfo(String extraInfo) {
this.ExtraInfo = extraInfo;
return this;
}
#Override
public BuildStep venue(String venue) {
this.Venue = venue;
return this;
}
#Override
public BuildStep template(String template) {
this.Template = template;
return this;
}
/**
* WARNING: Do not set ID when creating a new object. Leave this blank and one will be auto generated for you.
* This should only be set when referring to an already existing object.
* #param id id
* #return Current Builder instance, for fluent method chaining
* #throws IllegalArgumentException Checks that ID is in the proper format
*/
public BuildStep id(String id) throws IllegalArgumentException {
this.id = id;
try {
UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
} catch (Exception exception) {
throw new IllegalArgumentException("Model IDs must be unique in the format of UUID.",
exception);
}
return this;
}
}
public final class CopyOfBuilder extends Builder {
private CopyOfBuilder(String id, String eventTitle, String description, String eventDate, String eventTime, String category, String postUrl, String extraInfo, String venue, String template) {
super.id(id);
super.eventTitle(eventTitle)
.description(description)
.eventDate(eventDate)
.eventTime(eventTime)
.category(category)
.postUrl(postUrl)
.extraInfo(extraInfo)
.venue(venue)
.template(template);
}
#Override
public CopyOfBuilder eventTitle(String eventTitle) {
return (CopyOfBuilder) super.eventTitle(eventTitle);
}
#Override
public CopyOfBuilder description(String description) {
return (CopyOfBuilder) super.description(description);
}
#Override
public CopyOfBuilder eventDate(String eventDate) {
return (CopyOfBuilder) super.eventDate(eventDate);
}
#Override
public CopyOfBuilder eventTime(String eventTime) {
return (CopyOfBuilder) super.eventTime(eventTime);
}
#Override
public CopyOfBuilder category(String category) {
return (CopyOfBuilder) super.category(category);
}
#Override
public CopyOfBuilder postUrl(String postUrl) {
return (CopyOfBuilder) super.postUrl(postUrl);
}
#Override
public CopyOfBuilder extraInfo(String extraInfo) {
return (CopyOfBuilder) super.extraInfo(extraInfo);
}
#Override
public CopyOfBuilder venue(String venue) {
return (CopyOfBuilder) super.venue(venue);
}
#Override
public CopyOfBuilder template(String template) {
return (CopyOfBuilder) super.template(template);
}
}
public String getDayOfMonth() {
return EventDate.substring(5, 7);
}
public String getMonthOfYear() {
return EventDate.substring(0, 3);}
}
So far I have tried moving the eventAdapter.notifyDataSetChanged(); around to try to get it to work on 'run app'; however no matter where I put it it'll throw an error or it'll only show the data when I run it with debug.
I tried moving the:
//create the adapter
eventAdapter = new EventAdapter(getContext(), events);
//set a layout manager on RV
rvEvents.setLayoutManager(new LinearLayoutManager(getContext()));
//set the adapter on the recycler view
rvEvents.setAdapter(eventAdapter);
to different spots as well but it doesnt change anything. I dont know what I am doing wrong.
I had to change a few things as well as add a new thread and wait function:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
rvEvents = view.findViewById(R.id.rvEvents);
//set a layout manager on RV
rvEvents.setLayoutManager(new LinearLayoutManager(getContext()));
//set the adapter on the recycler view
rvEvents.setAdapter(eventAdapter);
amplifyAndSetAdapter();
//for some reason the code only works with both notifyDataSetChanged (other is in the other thread)
eventAdapter.notifyDataSetChanged();
}
private void amplifyAndSetAdapter() {
initializeAmplify();
amplifyQuery();
}
private void initializeAmplify() {
try {
// Add these lines to add the AWSApiPlugin plugins
Amplify.addPlugin(new AWSApiPlugin());
Amplify.configure(getApplicationContext());
Log.i(TAG, "Initialized Amplify");
} catch (AmplifyException error) {
Log.e(TAG, "Could not initialize Amplify", error);
}
}
private void amplifyQuery() {
Amplify.API.query(
ModelQuery.list(Event.class),
response -> {
for (Event event : response.getData()) {
Log.i("Amplify", "Title: " + event.getEventTitle() + " Date: " + event.getEventDate() + " Time: " + event.getEventTime()
+ " PostURL: " + event.getPostUrl() + " ExtraInfo: " + event.getExtraInfo() + " Venue: " + event.getVenue() + " Template: " + event.getTemplate());
addEvents(event);
}
//Used to seperate the ui using a wait function to add the proper time delay so that an error isnt thrown
Thread thread = new Thread(){
#Override
public void run() {
try {
synchronized (this) {
wait(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
eventAdapter.notifyDataSetChanged();
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}};
};
thread.start();
},
error -> Log.e("Amplify", "Query failure", error)
);
}
private void addEvents(Event event) {
try {
events.add(event);
Log.i(TAG, "Events: " + events.size());
} catch (Exception e) {
Log.e(TAG, "Events: ", e);
}
}
}
I'm new to android development application and i suppose to parse rss url into a listview. the code is working but we want to extract the images from the rss feed and display it into the listview.
RssItem.java
public class RssItem {
// item title
private String title;
// item link
private String link;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
#Override
public String toString() {
return title;
}
}
ListListener.java
public class ListListener implements OnItemClickListener {
// List item's reference
List<RssItem> listItems;
// Calling activity reference
Activity activity;
public ListListener(List<RssItem> aListItems, Activity anActivity) {
listItems = aListItems;
activity = anActivity;
}
/**
* Start a browser with url from the rss item.
*/
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(listItems.get(pos).getLink()));
activity.startActivity(i);
}
}
RssParseHandler.java
public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
// Used to reference item while parsing
private RssItem currentItem;
// Parsing title indicator
private boolean parsingTitle;
// Parsing link indicator
private boolean parsingLink;
public RssParseHandler() {
rssItems = new ArrayList<RssItem>();
}
public List<RssItem> getItems() {
return rssItems;
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
if ("item".equals(qName)) {
currentItem = new RssItem();
} else if ("title".equals(qName)) {
parsingTitle = true;
} else if ("link".equals(qName)) {
parsingLink = true;
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("item".equals(qName)) {
rssItems.add(currentItem);
currentItem = null;
} else if ("title".equals(qName)) {
parsingTitle = false;
} else if ("link".equals(qName)) {
parsingLink = false;
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (parsingTitle) {
if (currentItem != null)
currentItem.setTitle(new String(ch, start, length));
} else if (parsingLink) {
if (currentItem != null) {
currentItem.setLink(new String(ch, start, length));
parsingLink = false;
}
}
}
}
RssReader.java
public class RssReader {
private String rssUrl;
/**
* Constructor
*
* #param rssUrl
*/
public RssReader(String rssUrl) {
this.rssUrl = rssUrl;
}
/**
* Get RSS items.
*
* #return
*/
public List<RssItem> getItems() throws Exception {
// SAX parse RSS data
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
RssParseHandler handler = new RssParseHandler();
saxParser.parse(rssUrl, handler);
return handler.getItems();
}
}
ITCutiesReaderAppActivity.java
public class ITCutiesReaderAppActivity extends Activity {
// A reference to the local object
private ITCutiesReaderAppActivity local;
/**
* This method creates main application view
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set view
setContentView(R.layout.main);
// Set reference to this activity
local = this;
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://www.itcuties.com/feed/#sthash.YI6YrEet.dpuf");
// Debug the thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
}
public class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
#Override
protected List<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("ITCRssReader", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(List<RssItem> result) {
// Get a ListView from main view
ListView itcItems = (ListView) findViewById(R.id.listMainView1);
// Create a list adapter
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem> (local,android.R.layout.simple_list_item_1, result);
// Set list adapter for the ListView
itcItems.setAdapter(adapter);
// Set list view item click listener
itcItems.setOnItemClickListener(new ListListener(result, local));
}
}
}
After reading online for a few hours I got this, originally the code didn't parse the image but after reading documentation on DOM elements (from the documentation that comes with Android Studio), I was able to create the following code snippet which actually works. I tested it in a console.
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
* Created by user on 7/1/2016.
*/
public class FeedParser {
// names of the XML tags
static final String PUB_DATE = "pubDate";
static final String LINK = "link";
static final String TITLE = "title";
static final String ITEM = "item";
static final String IMAGE = "media:thumbnail";
static final String AUTHOR = "author";
final URL feedUrl;
public FeedParser(String feedUrl){
try {
this.feedUrl = new URL(feedUrl);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public InputStream getInputStream() {
try {
return feedUrl.openConnection().getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void parse() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName(ITEM);
for (int i=0;i<items.getLength();i++){
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for (int j=0;j<properties.getLength();j++){
Node property = properties.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase(TITLE)){
System.out.println(property.getFirstChild().getNodeValue());
} else if (name.equalsIgnoreCase(LINK)){
System.out.println(property.getFirstChild().getNodeValue());
} else if (name.equalsIgnoreCase(AUTHOR)){
StringBuilder text = new StringBuilder();
NodeList chars = property.getChildNodes();
for (int k=0;k<chars.getLength();k++){
text.append(chars.item(k).getNodeValue());
}
System.out.println(text.toString());
} else if (name.equalsIgnoreCase(PUB_DATE)){
System.out.println(property.getFirstChild().getNodeValue());
}
else if (name.equalsIgnoreCase(IMAGE)){
System.out.println(property.getAttributes().getNamedItem("url").getNodeValue());
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] aeg){
new FeedParser("http://www.pcworld.com/index.rss").parse();
}
}
Though my answer is late i hope it helps someone else
You are reinventing the wheel. You can simplify everything by using the android-rss library with droidQuery (originally posted here):
final RSSHandler handler = new RSSHandler(new RSSConfig());
$.ajax(new AjaxOptions().url(options.url())
.type("GET")
.dataType("XML")
.context(this)
.SAXContentHandler(handler)
.success(new Function() {
#Override
public void invoke($ droidQuery, Object... params) {
RSSFeed feed = handler.feed();
List<RSSItem> = feed.getItems();
//use this list to update your list adapter, then call the method "getThumbnails()" to get the images associated with the feed item.
}
}));
I'm working on a small app that uses and xml file to print an ArrayList of chapters which in turn points to a specific html file.
I used this tutorial to get me started: http://www.anddev.org/novice-tutorials-f8/parsing-xml-from-the-net-using-the-saxparser-t353.html
My xml file looks something like this:
<chapters>
<chapter title="Förutsättningar">
<page title="Sida 3" url="sida_3.html" />
<page title="Sida 4" url="sida_4.html" />
</chapter>
</chapters>
Using the tutorial above I've managed to output each chapter node into an ArrayList with a onListItemClick function on each item. So far so good.
The problem I'm having is that I can't figure out how to get a specific child node and load the html file when I click an item. I'm pretty new to Android.
Any ideas? I would really appreciate ANY help on the subject.
Here's my source:
ParsingXML.java
public class ParsingXML extends ListActivity {
private final String MY_DEBUG_TAG = "XmlParser";
public String lang = null;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setTitle("Lastsäkring");
Bundle bundle = this.getIntent().getExtras();
lang = bundle.getString("lang");
Log.i("ParsingXML", "Chosen language: " + this.lang + ", Type: " + this.lang.getClass().getName());
TextView tv = new TextView(this);
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
ExampleHandler myExampleHandler = new ExampleHandler();
xr.setContentHandler(myExampleHandler);
/*
* If XML-file is located online (needs internet permissions in the manifest):
* URL url = new URL("http://dev.houdini.se/android/demo.xml");
* xr.parse(new InputSource(url.openStream()));
*/
if(this.lang.equals("en"))
xr.parse(new InputSource(this.getResources().openRawResource(R.raw.en_content)));
else
xr.parse(new InputSource(this.getResources().openRawResource(R.raw.sv_content)));
ParsedExampleDataSet parsedExampleDataSet = myExampleHandler.getParsedData();
this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, parsedExampleDataSet.toArrayList()));
} catch(Exception e) {
tv.setText("Error: " + e.getMessage());
Log.e(MY_DEBUG_TAG, "XmlParseError", e);
this.setContentView(tv);
}
}
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
CharSequence text = "Clicked position: " + position + ", id: " + id;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
/*switch( position )
{
case 0:
Bundle bundle = new Bundle();
bundle.putString("WindowTitle", "TESTA");
Intent intent = new Intent(this, TextPage.class);
intent.putExtras(bundle);
startActivity(intent);
break;
case 1:
Intent video = new Intent(this, Video.class);
startActivity(video);
break;
case 2:
Intent swipe = new Intent(this, Swipe.class);
startActivity(swipe);
break;
}*/
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.settings:
Intent prefsActivity = new Intent(getBaseContext(), Preferences.class);
startActivity(prefsActivity);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
ExampleHandler.java
public class ExampleHandler extends DefaultHandler {
private boolean in_chapters = false;
private boolean in_chapter = false;
private boolean in_page = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
#Override
public void endDocument() throws SAXException {
// Nothing to do
}
#Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(localName.equals("chapters")) {
this.in_chapters = true;
} else if(localName.equals("chapter")) {
this.in_chapter = true;
String attrValue = atts.getValue("title");
myParsedExampleDataSet.setExtractedString(attrValue);
} else if(localName.equals("page")) {
this.in_page = true;
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if(localName.equals("chapters")) {
this.in_chapters = false;
} else if(localName.equals("chapter")) {
this.in_chapter = false;
} else if(localName.equals("page")) {
this.in_page = false;
}
}
#Override
public void characters(char ch[], int start, int length) {
if(this.in_page == true) {
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
}
}
}
ParsedExampleDataSet.java
public class ParsedExampleDataSet {
private String extractedString = "";
private ArrayList<String> myArr = new ArrayList<String>();
private int extractedInt = 0;
public ArrayList<String> getExtractedString() {
//return extractedString; Function Type = String
return myArr;
}
public void setExtractedString(String extractedString) {
//this.extractedString += extractedString + "\n";
myArr.add(extractedString);
}
public int getExtractedInt() {
return extractedInt;
}
public void setExtractedInt(int extractedInt) {
this.extractedInt = extractedInt;
}
public String toString() {
return "NODER\n" + this.extractedString;
}
public ArrayList<String> toArrayList() {
return this.myArr;
}
}
First create proper data structure:
public class PageNode {
public String title;
public String url;
/* Getters/setter/constructor etc. if you feel like*/
public String toString() {
return title;
}
}
public class ChapterNode {
public String title;
public ArrayList<PageNode> pages = new ArrayList<PageNode>();
/* Getters/setter/constructor etc. if you feel like*/
}
And parse the xml accordingly. Example:
ArrayList<ChapterNode> chapters = new ArrayList<ChapterNode>();
ChapterNode chapterNode = null;
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(localName.equals("chapters")) {
} else if(localName.equals("chapter")) {
chapterNode = new ChapterNode();
chapterNode.title = atts.getValue("title");
} else if(localName.equals("page")) {
PageNode pageNode = new PageNode();
pageNode.title = atts.getValue("title");
pageNode.url = atts.getValue("url");
chapterNode.pages.add(pageNode);
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if(localName.equals("chapters")) {
} else if(localName.equals("chapter")) {
chapters.add(chapterNode);
chapterNode = null;
} else if(localName.equals("page")) {
}
}
Then you can access the pageNode like this:
PageNode pageNode = chapterNode.pages.get(position);
And set adapter like this:
this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, chapterNode.pages));
You have to check for boolean variables while chapter tag is true you have to add pages in one arraylist and when chapter tag is false you have to add that arraylist in another gloabl arraylist
(Without having looked at the example tutorial...)
Have a look at the Attributes parameter of startElement in your example handler. It should contain a value for "url" (it looks like you're only getting the value for "title").
I'm used to using DocumentBuilderFactory, so my solution is:
firstly, you should create ArrayHelper class like this:
public class ArrayHelper {
public static ArrayList<HashMap<String, ?>> list = new ArrayList<HashMap<String, ?>>();
}
than:
public class CoversParseTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
}
#Override
protected Boolean doInBackground(Void ... arg0) {
try {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
document = dBuilder.parse(new InputSource(this.getResources().openRawResource(R.raw.en_content)));
document.getDocumentElement().normalize();
NodeList nodeListIssue = document.getElementsByTagName("page");
for (int i = 0; i < nodeListIssue.getLength(); i++) {
HashMap<String, Object> temp = new HashMap<String, Object>();
Node node = nodeListIssue.item(i);
Element elementMain = (Element) node;
String pageID = elementMain.getAttribute("title");
String issueID = elementMain.getAttribute("url");
temp.put("title", pageID);
temp.put("url", issueID);
ArrayHelper.list.add(temp);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
};
return false;
}
#Override
protected void onPostExecute(Boolean result) {
//what happend if done.
}
}
and execute this class like this:
new CoversParseTask().execute();
now we must create simple adapter:
SimpleAdapter adapter = new MySimpleAdapter(this, selectLastSearch(), R.layout.custom_row_view, new String[] { "Title", "Url" }, new int[] { R.id.title, R.id.url});
and our MySimpleAdapter looks like this:
public class MySimpleAdapter extends SimpleAdapter {
Context localcontext = null;
public MySimpleAdapter(Context context,List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
localcontext = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
return view;
}
}
noe set adapter to listview:
listview.setAdapter(adapter);
if You want to get URL from list, you should add listner to listview like this:
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view,
int position, long arg) {
Log.v("URL", ArrayHelper.list.get(position).get("url").toString());
}
});
and thats all, i hope that i help you :)
I'm trying to follow this tutorial http://automateddeveloper.blogspot.com/2011/05/android-rss-reader-20.html
I'm using eclipse and developing for android 2.0
here is the problem
*I cant figure out how to set an onclick listener or something similar to each article
*I'm trying to make it go to the website the article is from onclick
public class Utezone extends ListActivity {
private RssListAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<JSONObject> jobs = new ArrayList<JSONObject>();
try {
jobs = RssReader.getLatestRssFeed();
} catch (Exception e) {
Log.e("RSS ERROR", "Error loading RSS Feed Stream >> " + e.getMessage() + " //" + e.toString());
}
adapter = new RssListAdapter(this,jobs);
setListAdapter(adapter);
}
}
public class RssListAdapter extends ArrayAdapter<JSONObject> {
public RssListAdapter(Activity activity, List<JSONObject> imageAndTexts) {
super(activity, 0, imageAndTexts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Activity activity = (Activity) getContext();
LayoutInflater inflater = activity.getLayoutInflater();
// Inflate the views from XML
View rowView = inflater.inflate(R.layout.image_text_layout, null);
JSONObject jsonImageText = getItem(position);
//////////////////////////////////////////////////////////////////////////////////////////////////////
//The next section we update at runtime the text - as provided by the JSON from our REST call
////////////////////////////////////////////////////////////////////////////////////////////////////
TextView textView = (TextView) rowView.findViewById(R.id.job_text);
try {
Spanned text = (Spanned)jsonImageText.get("text");
textView.setText(text);
} catch (JSONException e) {
textView.setText("JSON Exception");
}
return rowView;
}
}
public class RssReader {
private final static String BOLD_OPEN = "<B>";
private final static String BOLD_CLOSE = "</B>";
private final static String BREAK = "<BR>";
private final static String ITALIC_OPEN = "<I>";
private final static String ITALIC_CLOSE = "</I>";
private final static String SMALL_OPEN = "<SMALL>";
private final static String SMALL_CLOSE = "</SMALL>";
/**
* This method defines a feed URL and then calles our SAX Handler to read the article list
* from the stream
*
* #return List<JSONObject> - suitable for the List View activity
*/
public static List<JSONObject> getLatestRssFeed(){
String feed = "thefeedurl";
RSSHandler rh = new RSSHandler();
List<Article> articles = rh.getLatestArticles(feed);
Log.e("RSS ERROR", "Number of articles " + articles.size());
return fillData(articles);
}
/**
* This method takes a list of Article objects and converts them in to the
* correct JSON format so the info can be processed by our list view
*
* #param articles - list<Article>
* #return List<JSONObject> - suitable for the List View activity
*/
private static List<JSONObject> fillData(List<Article> articles) {
List<JSONObject> items = new ArrayList<JSONObject>();
for (Article article : articles) {
JSONObject current = new JSONObject();
try {
buildJsonObject(article, current);
} catch (JSONException e) {
Log.e("RSS ERROR", "Error creating JSON Object from RSS feed");
}
items.add(current);
}
return items;
}
/**
* This method takes a single Article Object and converts it in to a single JSON object
* including some additional HTML formating so they can be displayed nicely
*
* #param article
* #param current
* #throws JSONException
*/
private static void buildJsonObject(Article article, JSONObject current) throws JSONException {
String title = article.getTitle();
String description = article.getDescription();
String date = article.getPubDate();
StringBuffer sb = new StringBuffer();
sb.append(BOLD_OPEN).append(title).append(BOLD_CLOSE);
sb.append(BREAK);
sb.append(description);
sb.append(BREAK);
sb.append(SMALL_OPEN).append(ITALIC_OPEN).append(date).append(ITALIC_CLOSE).append(SMALL_CLOSE);
current.put("text", Html.fromHtml(sb.toString()));
}
}
Since the activity extends ListActivity you can simply do:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
//do something
}
A onclicklistener is bound to a listview. call getListView() and set it to a ListView ivar. On that ivar implement an OnItemClickListener by calling the method setOnItemClickListener();
ListView lw = getListView();
lw.setOnItemClickListener(new OnItemClickListener({
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {}
}));
I'm getting a json exception when I try to run my code.
The problem happens on the onclick listener. I'm trying to have the application go to the article of the rss feed on click
Here is the main activity
public class Blocku extends ListActivity {
private RssListAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<JSONObject> jobs = new ArrayList<JSONObject>();
try {
jobs = BlockuReader.getLatestRssFeed();
} catch (Exception e) {
Log.e("RSS ERROR", "Error loading RSS Feed Stream >> " + e.getMessage() + " //" + e.toString());
}
adapter = new RssListAdapter(this,jobs);
setListAdapter(adapter);
}
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
String link = null;
try {
String url = Article.getUrl().toString();
link = adapter.getItem(position).getString(url).toString();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(link));
startActivity(i);
} catch (JSONException e) {
Context context = getApplicationContext();
CharSequence text = "error";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
e.printStackTrace();
}
}
}
here is the adapter:
public class RssListAdapter extends ArrayAdapter<JSONObject> {
public RssListAdapter(Activity activity, List<JSONObject> imageAndTexts) {
super(activity, 0, imageAndTexts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Activity activity = (Activity) getContext();
LayoutInflater inflater = activity.getLayoutInflater();
// Inflate the views from XML
View rowView = inflater.inflate(R.layout.image_text_layout, null);
JSONObject jsonImageText = getItem(position);
//////////////////////////////////////////////////////////////////////////////////////////////////////
//The next section we update at runtime the text - as provided by the JSON from our REST call
////////////////////////////////////////////////////////////////////////////////////////////////////
TextView textView = (TextView) rowView.findViewById(R.id.job_text);
try {
Spanned text = (Spanned)jsonImageText.get("text");
textView.setText(text);
} catch (JSONException e) {
textView.setText("JSON Exception");
}
return rowView;
}
}
and the article class
public class Article {
private long articleId;
private long feedId;
private String title;
private String description;
private String pubDate;
private static URL url;
private String encodedContent;
private static String link;
/**
* #return the articleId
*/
public long getArticleId() {
return articleId;
}
/**
* #param articleId the articleId to set
*/
public void setArticleId(long articleId) {
this.articleId = articleId;
}
/**
* #return the feedId
*/
public long getFeedId() {
return feedId;
}
/**
* #param feedId the feedId to set
*/
public void setFeedId(long feedId) {
this.feedId = feedId;
}
/**
* #return the title
*/
public String getTitle() {
return title;
}
/**
* #param title the title to set
*/
public void setTitle(String title) {
this.title = title;
}
/**
* #return the url
*/
public static URL getUrl() {
return url;
}
/**
* #param url the url to set
*/
public void setUrl(URL url) {
Article.url = url;
}
/**
* #param description the description to set
*/
public void setDescription(String description) {
this.description = description;
}
/**
* #return the description
*/
public String getDescription() {
return description;
}
/**
* #param pubDate the pubDate to set
*/
public void setPubDate(String pubDate) {
this.pubDate = pubDate;
}
/**
* #return the pubDate
*/
public String getPubDate() {
return pubDate;
}
/**
* #param encodedContent the encodedContent to set
*/
public void setEncodedContent(String encodedContent) {
this.encodedContent = encodedContent;
}
/**
* #return the encodedContent
*/
public String getEncodedContent() {
return encodedContent;
}
}
JSONException is usually thrown when there are issues with parsing. Check how you are parsing the JSON. this says that you are trying to get a value for a key named "then it lists the site i want"