0

Having difficulty with this. I'm wanting to use a database to get data from the Add Reminder page to the Reminder page which contains a list view.

This is the database file

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MOSDatabase extends SQLiteOpenHelper  {

    private static final int DATABASE_VERSION = 2;
    public static final String TABLE_NAME = "ReminderTable";


    private static final String TABLE_CREATE = "create table " + TABLE_NAME + " (" +
            "PTITLE" + " TEXT ," + //HEADING FOR MINUTE SELECTED IN TIMEPICKER
            "PA" + " TEXT ," + //PAYMENT VALUE
            "PDAY" + " TEXT ," + //DAY SELECTED IN DATEPICKER
            "PMONTH" + " TEXT ," + //MONTH SELECTED IN DATEPICKER
            "PYEAR" + " TEXT ," + //YEAR SELECTED IN DATEPICKER
            "RDAY" + " TEXT ," + //REMINDER DAY
            "RMONTH" + " TEXT ," + //REMINDER MONTH
            "RYEAR" + " TEXT ," + //REMINDER YEAR
            "RMIN" + " TEXT ," + //REMINDER MIN
            "RHOUR" + " TEXT);"; //REMINDER HOUR

    MOSDatabase(Context context){
        super(context, "MOSDatabase", null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
        db.execSQL(TABLE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        this.onCreate(db);
    }


}

This is the CustomAdapter used in my Reminder page

    import java.util.ArrayList;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class CustomAdapter extends ArrayAdapter<String> {


    Cursor C;
    SharedPreferences prefs;
    String color;
    String text_color;
    String bgcolor;


    public CustomAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
        // TODO Auto-generated constructor stub
    }


    public ArrayList<String> paymentTitle;
    public ArrayList<String> paymentDate;
    public ArrayList<String> reminderTime;
    public ArrayList<String> reminderDate;
    public ArrayList<String> paymentAmount;


   // Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "Roboto-Light.ttf");


    public CustomAdapter(Context context, int resource, ArrayList<String> pt, ArrayList<String> pd, ArrayList<String> rd, ArrayList<String> rt, ArrayList<String> pa) {

        super(context, resource, pt);

        this.paymentTitle = pt;
        this.paymentDate = pd;
        this.reminderDate = rd;
        this.reminderTime = rt;
        this.paymentAmount = pa;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;

        if (v == null) {

            LayoutInflater vi;
            vi = LayoutInflater.from(getContext());
            v = vi.inflate(R.layout.item_row, null);

        }

        //Get the corresponding string for the position of arraylist
        String paymentTimeStr = paymentTitle.get(position).toString();
        String paymentDateStr = paymentDate.get(position).toString();
        String reminderDateStr = reminderDate.get(position).toString();
        String reminderTimeStr = reminderTime.get(position).toString();
        String paymentValueStr = paymentAmount.get(position).toString();


        //FIND THE TEXTVIEWS FROM YOUR INDIVIDUAL LAYOUT
        TextView payDateTV = (TextView) v.findViewById(R.id.txtPaymentDate);
        TextView payTitleTV = (TextView) v.findViewById(R.id.txtTitle);
        TextView reminderDateTV = (TextView) v.findViewById(R.id.txtReminderDate);
        TextView reminderTimeTV = (TextView) v.findViewById(R.id.txtReminderTime);
        TextView paymentValueTV = (TextView) v.findViewById(R.id.txtAmount);


        if (payDateTV != null) {
            payDateTV.setText(paymentDateStr);
        }

        if (payTitleTV != null) {
            payTitleTV.setText(paymentTimeStr);
        }

        if (reminderDateTV != null) {
            reminderDateTV.setText(reminderDateStr);
        }

        if (reminderTimeTV != null) {
            reminderTimeTV.setText(reminderTimeStr);
        }

        if (paymentValueTV != null) {
            paymentValueTV.setText(paymentValueStr);
        }

        return v;

    }
}

This is the Reminder page

public class Reminders extends Activity
{
    TextView title;
    Button add, edit, remove;
    ListView mListView;

    ArrayList<String> paymentTitle = new ArrayList<String>();
    ArrayList<String> paymentDate = new ArrayList<String>();
    ArrayList<String> reminderDate = new ArrayList<String>();
    ArrayList<String> reminderTime = new ArrayList<String>();
    ArrayList<String> paymentVal = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.reminders);
        initializeVariables();

        MOSDatabase mDatabase = new MOSDatabase(this);

        //DEFINE CUSTOM ADAPTER
        CustomAdapter aa = new CustomAdapter(this, R.layout.item_row, paymentTitle, paymentDate, reminderDate, reminderTime, paymentVal);

        //SET CUSTOM ADAPTER FOR LISTVIEW
        mListView.setAdapter(aa);

        // READING A DB
        SQLiteDatabase readableDB = mDatabase.getReadableDatabase();
        Cursor C = readableDB.query("ReminderTable", new String[] { "PTITLE", "PA", "PDAY", "PMONTH", "PYEAR", "RDAY", "RMONTH",
                "RYEAR", "RMIN", "RHOUR" }, null, null, null, null, null);

        if (C == null)
        {
            title.setText("No Upcoming Payments");
        }
        else{
            C.moveToFirst();
            do {
                String reminderDateStr = "";
                String reminderTimeStr = "";
                String paymentDateStr = "";
                String paymentTitleStr = "";
                String paymentValue = "";

                //Build strings of each record to then be set to the listview
                reminderDateStr = C.getString(5) + "/" + C.getString(6)+ "/" +C.getString(7);
                reminderTimeStr = C.getString(8) + ":" + C.getString(9);
                paymentDateStr = C.getString(2) + "/" + C.getString(3) + "/" + C.getString(4);
                paymentTitleStr = C.getString(0);
                paymentValue = C.getString(1);

                //Add the new strings to the corresponding array
                paymentTitle.add(paymentTitleStr);
                reminderTime.add(reminderTimeStr);
                paymentDate.add(paymentDateStr);
                reminderDate.add(reminderDateStr);
                paymentVal.add(paymentValue);

            } while (C.moveToNext());
        }



        //CLOSE CURSOR AND DATABASE TO AVOID MEMORY LEAKS
        C.close();
        readableDB.close();

        //TELL ADAPTER THERE IS NEW DATA SO UPDATE THE LISTVIEW ACCORDINGLY
        aa.notifyDataSetChanged();

    }

    private void initializeVariables()
    {
        title = (TextView) findViewById(R.id.txtTitle);
        add = (Button) findViewById(R.id.bAdd);
        edit = (Button) findViewById(R.id.bEdit);
        remove = (Button) findViewById(R.id.bRemove);
        mListView = (ListView) findViewById(R.id.LVReminder);
    }

    public void addClicked(View view)
    {
        Intent openNewPayment = new Intent("com.studentbudget.ADDREMINDER");
        startActivity(openNewPayment);
        finish();
    }
}

When I ran my application and clicked on the Reminder link, it didn't open and crashed. This is the logcat:

08-04 23:02:59.798  10548-10548/com.studentbudget E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.studentbudget/com.studentbudget.Reminders}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
        at android.app.ActivityThread.access$600(ActivityThread.java:141)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
        at android.database.AbstractCursor.checkPosition(AbstractCursor.java:424)
        at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
        at com.studentbudget.Reminders.onCreate(Reminders.java:66)
        at android.app.Activity.performCreate(Activity.java:5133)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
        ... 11 more

Line 66 is this:

reminderDateStr = C.getString(5) + "/" + C.getString(6)+ "/" +C.getString(7);

I've tried changing it so it was reminderDateStr = "Test"; and it worked so there's something wrong with the C.getString(num) method and I don't know what it is.

Thanks to anyone who helps me get this fixed.

4 Answers 4

1

C.moveToFirst() returns false if there is no entry in the cursor. Check it because this will cause an CursorIndexOutOfBoundsException if there is no entry.

Also always check if there is the row and get the right cursor index like C.getColumnIndex("RDAY")

if(C.moveToFirst()) {
    do {
        String reminderDateStr = "";
        String reminderTimeStr = "";
        String paymentDateStr = "";
        String paymentTitleStr = "";
        String paymentValue = "";

        //Build strings of each record to then be set to the listview
        reminderDateStr = C.getString(C.getColumnIndex("RDAY")) + "/" + C.getString(C.getColumnIndex("RMONTH"))+ "/" +C.getString(C.getColumnIndex("RYEAR"));
        reminderTimeStr = C.getString(C.getColumnIndex("RHOUR")) + ":" + C.getString(C.getColumnIndex("RMIN"));
        paymentDateStr = C.getString(C.getColumnIndex("PDAY")) + "/" + C.getString(C.getColumnIndex("PMONTH")) + "/" + C.getString(C.getColumnIndex("PYEAR"));
        paymentTitleStr = C.getString(C.getColumnIndex("PTITLE"));
        paymentValue = C.getString(C.getColumnIndex("PA"));

        //Add the new strings to the corresponding array
        paymentTitle.add(paymentTitleStr);
        reminderTime.add(reminderTimeStr);
        paymentDate.add(paymentDateStr);
        reminderDate.add(reminderDateStr);
        paymentVal.add(paymentValue);

    } while (C.moveToNext());
}
Sign up to request clarification or add additional context in comments.

Comments

1
reminderDateStr = C.getString(C.getColumnIndex("RDAY")) + "/" +
                  C.getString(C.getColumnIndex("RMONTH"))+ "/" + 
                  C.getString(C.getColumnIndex("RYEAR"));

Hope it helps you.

Comments

1

It's probably this line:

C.moveToFirst();

combined with

while (C.moveToNext());

Using these two lines will end up in incrementing beyond the scope of the Cursor.

Instead of doing that, simply use

while (c.moveToNext()) {
    // Retrieve data here
}

c.close();

1 Comment

Didn't work, it keeps saying there's an error on the same line
1

You are getting a 0 size cursor and you try to read it. I suggest changing your cursor reading code to:

if (C == null || !C.moveToFirst())
    {
        title.setText("No Upcoming Payments");
    }
    else{
        do {
            String reminderDateStr = "";
            ...
            //Build strings of each record to then be set to the listview
            ...
            //Add the new strings to the corresponding array
       } while (C.moveToNext());
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.