Search code examples
javaandroidsqlitersssimplecursoradapter

Storing parsed Rss items within SQLite


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);


}}

Solution

  • 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)