As my first Android project I'm trying to make an RSS reader app in which Listview items can be saved to SQLite, allowing them to be read offline. However, when trying to return news titles in a listView using a query with SimpleCursorAdapter, the listview displays the text "title", rather than the actual title of the news.
This seems to suggest that the items are not being stored to the database, or that the content values are not being properly assigned.
Can anybody see where i might be going wrong?
Thanks in advance!
RssItem.java
public class RssItem {
protected String _id;
public String title;
protected String link;
protected String page;
protected String completeTextLink;
protected String mainBody;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
//Title get/set
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
//Link get/set
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
//CompleteTextLink get/set
public String getCompleteTextLink() {
return completeTextLink;
}
public void setCompleteTextLink(String completeTextLink) {
this.completeTextLink = completeTextLink;
}
//MainBody get/set
public String getMainBody() {
return mainBody;
}
public void setMainBody(String mainBody) {
this.mainBody = mainBody;
}
//Page get/set
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
@Override
public String toString() {
return title;
}}
MainActivity.java
public class MainActivity extends Activity {
private MainActivity local;
private DatabaseHandler db;
//Method to create main application view
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set view
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//**************************create a button to move to the user's saved feeds screen*****************************
Button myFeedsButton = (Button) findViewById(R.id.myFeedsButton);
myFeedsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
startActivity(new Intent(MainActivity.this, MyFeedsScreen.class));
}
});
//***************************************************************************************************************
//Create new instance of database handler
db = new DatabaseHandler(this);
//set local ref to this activity
local = this;
GetRSSDataTask task = new GetRSSDataTask();
//start download Rss task - execute method calls the
task.execute("http://feeds.bbci.co.uk/news/rss.xml?edition=uk");
//debug thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
}
//*******************************************************************************************************************
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem>>
{
@Override
protected List<RssItem> doInBackground(String... urls) {
//debug task thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
try {
//create a new reader
RssReader rssReader = new RssReader(urls[0]);
//Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("RssReaderApp", e.getMessage());
}
return null;
}//doInBackground
//is invoked on UI thread after background tasks are complete.
// Results of background task are passed here as a parameter
@Override
protected void onPostExecute(List<RssItem> result)
{
//Gets listview from main.xml
final ListView listItems = (ListView) findViewById(R.id.listMainView);
//Creates a new list adapter - displays an array of strings in listview
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(local, android.R.layout.simple_list_item_1, result);
//Set list adapter for listView
listItems.setAdapter(adapter);
//OnItemClick listener set to allow user to access content from title
listItems.setOnItemClickListener(new ListListener(result, local));
//*******************************LONG CLICK FUNCTIONALITY******************************************
//Set new long click listener which should allow item to be stored to db
listItems.setLongClickable(true);
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
try {
db.open();
RssItem item = new RssItem();
item.title = "title";
item.link = "link";
item.completeTextLink ="completeTextLink";
item.page = "page";
db.insertRssItem(item);
db.close();
} catch (SQLException e)
{
e.printStackTrace();
}
Toast.makeText(getBaseContext(), "Item saved in My Feeds!", Toast.LENGTH_SHORT).show();
return true;
}
});
}//onPostExecute
}}//class
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "news_db";
public static SQLiteDatabase db;
private static final int DATABASE_VERSION = 32;
protected static final String TABLE_NEWS = "news";
private static final String TAG = "TAG";
private static final String TAG1 = "TAG1";
static String columnTitle = "title";
protected static final String _id = "_id";
//Methods for tables
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_NEWS = "CREATE TABLE " + TABLE_NEWS + "(_id VARCHAR, title TEXT, link TEXT, completeTextLink TEXT, mainBody Text, page TEXT)";
db.execSQL(CREATE_TABLE_NEWS);
Log.w(TAG, "Database has been created");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NEWS);
onCreate(db);
}
public void open() throws SQLException {
db = this.getWritableDatabase();
}
//Method to insert new rssItem object to the database
public void insertRssItem(RssItem rssItem) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("_id", rssItem._id);
contentValues.put("title", rssItem.title);
contentValues.put("link", rssItem.link);
contentValues.put("mainBody", rssItem.mainBody);
contentValues.put("completeTextLink", rssItem.completeTextLink);
contentValues.put("page", rssItem.page);
db.insert(TABLE_NEWS, "title", contentValues);
Log.d(TAG1, "ITEM SAVED IN DATABASE!!!");
}//insert item method
//Method to return all news for a given item
public List<RssItem> getAllNewsForItem(String page) {
List<RssItem> SavedNewsList = new ArrayList<RssItem>();
Cursor cursor = db.rawQuery("select _id, completeTextLink, title, link, mainBody, page" +
" FROM " + TABLE_NEWS + " where page = ?", new String[]{page});
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
RssItem rssItem = new RssItem();
rssItem._id = cursor.getString(0);
rssItem.completeTextLink = cursor.getString(1);
rssItem.title = cursor.getString(2);
rssItem.link = cursor.getString(3);
rssItem.mainBody = cursor.getString(4);
rssItem.page = page;
SavedNewsList.add(rssItem);
cursor.moveToNext();
}
cursor.close();
return SavedNewsList;
}
//get data from database for listview
public Cursor getData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NEWS, null);
return cursor;
}}
MyFeedsScreen.java
public class MyFeedsScreen extends ListActivity {
DatabaseHandler dbHandler;
SimpleCursorAdapter dataAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_feeds_screen);
dbHandler = new DatabaseHandler(MyFeedsScreen.this);
displayList();
}
public void displayList() {
dbHandler.getWritableDatabase();
dbHandler = new DatabaseHandler(this);
Cursor cursor = dbHandler.getData();
String from[] = new String[]{dbHandler.columnTitle};
int to[] = new int[]{R.id.textView1};
dataAdapter = new SimpleCursorAdapter(this, R.layout.row_item, cursor, from, to, 0);
ListView lv = getListView();
lv.setAdapter(dataAdapter);
}}
You should call getItemAtPosition(int position)
from within your long-press listener. That will get you the Object
from the collection that backs the ListView, in this case, the article from your RssReader that the user long-pressed upon. Sorta like:
...
db.open();
RssArticleThing fromList = (RssArticleThing) listItems.getItemAtPosition(position);
RssItem item = new RssItem();
item.title = fromList.title;
...
http://developer.android.com/reference/android/widget/AdapterView.html#getItemAtPosition(int)