0

When my app loads for the first time the data is being added to the app ,and the user can use whatever he/she wants. The problem is when i add more data to the same table ,lets say i add more data in an update. Than the code starts to crash and to tell me that:

android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0

I have figured out that my cursor is null ,but i have no idea why.

The database is not opened ,and I have closed it properly. Here is my code:

The adding to database part:

public class Database {


    private Dbhelper dbhelper;
    SQLController dbcon;
    private SQLiteDatabase database;
    Context context;

    public Database(Dbhelper dbhelper, SQLController dbcon, SQLiteDatabase database, Context context) {
        this.dbhelper = dbhelper;
        this.database = database;
        this.dbcon = dbcon;
        this.context = context;
    }


    public boolean addToDatabase() {
        boolean isTrue = false;
        ///
        try {

            dbcon.open();
            int plan_i = dbcon.countPlanStock().getCount();
            dbcon.close();

            if (plan_i < 3) {

                dbcon.open();
                dbcon.deletePlanSAll();
                dbcon.close();

                //REST = REST
                dbcon.open();
                dbcon.insertPlanStock("Newbie", "Free", "ic_newbie", "7 Days", "5 8 12 REST 7 REST 1", "false false false false false false false");
                dbcon.close();

                dbcon.open();
                dbcon.insertPlanStock("Alpha 10", "Pro version", "ic_alphaten", "14 Days", "1 8 5 12 4 10 REST 11 REST 1 6 REST 2 5", "false false false false false false false false false false false false false false");
                dbcon.close();

                dbcon.open();
                dbcon.insertPlanStock("Alpha V2", "Pro version", "ic_alphav2", "30 Days", "1 3 11 10 13 REST REST 5 4 11 12 8 REST REST 3 7 13 11 REST 13 12 REST REST 6 12 4 1 REST 12 13", "false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false");
                dbcon.close();
            }


            dbcon.open();
            int workout_i = dbcon.countDataS().getCount();
            dbcon.close();

            if (workout_i < 17) {

                dbcon.open();
                dbcon.deleteAllFromStockWorkouts();
                dbcon.close();

                dbcon.open();
                dbcon.insertDataStock("INTENSE MMA CIRCUIT", " ENDURANCE ", " DEFINITION ", " CORE ", "16min", "NO EQUIPMENT REQUIRED", "3",
                        "pushups uppercuts slow_pushups quick_punches",//round 1
                        "jump_squat_180 burpee_hill_climb short_jumps",//round 2
                        "leg_raises tyson_neck_raise spartan_pushups",//round 3
                        "",//round 4
                        "",//round 5
                        "",//round 6
                        "",//round 7
                        "",//round 8
                        "",//round 9
                        "",//round 10
                        "",//round 11
                        "",//round 12


                        "40000",//rest 1
                        "40000",//rest 2
                        "40000",//rest 3
                        "",//rest 4
                        "",//rest 5
                        "",//rest 6
                        "",//rest 7
                        "",//rest 8
                        "",//rest 9
                        "",//rest 10
                        "",//rest 11
                        "",//rest 12

                        "10x 30x 5x 50x",//reps round 1
                        "5x 10x 10x",//reps round 2
                        "10x 5x 10x",//reps round 3
                        "",//reps round 4
                        "",//reps round 5
                        "",//reps round 6
                        "",//reps round 7
                        "",//reps round 8
                        "",//reps round 9
                        "",//reps round 10
                        "",//reps round 11
                        "",//reps round 12

                        "intense_mma_circuit_1",//round exercises 1
                        "intense_mma_circuit_2",//round exercises 2
                        "intense_mma_circuit_3",//round exercises 3
                        "",//round exercises 4
                        "",//round exercises 5
                        "",//round exercises 6
                        "",//round exercises 7
                        "",//round exercises 8
                        "",//round exercises 9
                        "",//round exercises 10
                        "",//round exercises 11
                        "",//round exercises 12

                        "300000",//reps round 1 main
                        "300000",//reps round 2 main
                        "300000",//reps round 3 main
                        "",//reps round 4 main
                        "",//reps round 5 main
                        "",//reps round 6 main
                        "",//reps round 7 main
                        "",//reps round 8 main
                        "",//reps round 9 main
                        "",//reps round 10 main
                        "",//reps round 11 main
                        "",//reps round 12 main


                        "10",//rest exercise round 1 main
                        "10",//rest exercise round 2 main
                        "10",//rest exercise round 3 main
                        "",//rest exercise round 4 main
                        "",//rest exercise round 5 main
                        "",//rest exercise round 6 main
                        "",//rest exercise round 7 main
                        "",//rest exercise round 8 main
                        "",//rest exercise round 9 main
                        "",//rest exercise round 10 main
                        "",//rest exercise round 11 main
                        "",//rest exercise round 12 main
                        "0",//workout type


                        "- - -",//Exercise Rest Round 1
                        "- -",//Exercise Rest Round 2
                        "- -",//Exercise Rest Round 3
                        "",//Exercise Rest Round 4
                        "",//Exercise Rest Round 5
                        "",//Exercise Rest Round 6
                        "",//Exercise Rest Round 7
                        "",//Exercise Rest Round 8
                        "",//Exercise Rest Round 9
                        "",//Exercise Rest Round 10
                        "",//Exercise Rest Round 11
                        ""//Exercise Rest Round 12


                );
                dbcon.close();


                ......
            }



        } finally {
            isTrue = true;
        }


        return isTrue;
    }


}

There is an async task that takes care of this ,i just this class as a helper.

The Adapter class where the problem occurs when the data is being added afterwards:

public class PlanAdapter extends AppCompatActivity {
    private Toolbar toolbar;
    private Dbhelper dbhelper;
    SQLController dbcon;
    private SQLiteDatabase database;
    SQLController adapter;
    String[] wokrouts_A;
    String wokrouts_S;

    public String[] isDone_A;
    public String isDone_S;
    public boolean isDone[];
    private ProgressBar progressBar;
    public int bool_counter = 0;

    private String Plan_Name = "TEST";
    private TextView Plan_Days_Coutner;

    RecyclerView recyclerView;
    PlanRecyclerAdapter ca;

    int current_day = 0;

    String[] workout_name_shortener;


    private DBhelper dbhelper_l;
    private SQLiteDatabase database_l;
    SQLiteController dbcon_l;
    String date = new SimpleDateFormat("d.M.yyyy").format(new Date());

    ProgressBar pm_navigation;
    List<Integer> Tab_Colour = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.plan_adapter);


        adapter = new SQLController(this);
        dbcon = new SQLController(this);
        dbhelper = new Dbhelper(this);
        database = dbhelper.getWritableDatabase();


        dbcon_l = new SQLiteController(this);
        dbhelper_l = new DBhelper(this);
        database_l = dbhelper_l.getWritableDatabase();

        Intent intent = getIntent();
        Plan_Name = intent.getStringExtra("plan_info");

        toolbar = (Toolbar) findViewById(R.id.app_bar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Typeface faceRobotoMedium = Typeface.createFromAsset(getResources().getAssets(), "Roboto-Medium.ttf");
        TextView TitleBarCustom = (TextView) findViewById(R.id.toolbar_title);
        TitleBarCustom.setTypeface(faceRobotoMedium);

        TitleBarCustom.setText("" + Plan_Name);
        getSupportActionBar().setTitle(null);

        Plan_Days_Coutner = (TextView) findViewById(R.id.plan_coutner_id);
        Plan_Days_Coutner.setTypeface(faceRobotoMedium);


        recyclerView = (RecyclerView) findViewById(R.id.recyclerList);
        LinearLayoutManager llm = new LinearLayoutManager(this);
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(llm);
        ca = new PlanRecyclerAdapter(generateWorkouts(), isDone, bool_counter, Plan_Name, getApplicationContext(), dbhelper, dbcon, database);
        //ca.setClickListener(this);
        recyclerView.setAdapter(ca);

        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setProgress(current_day);
        progressBar.setMax(isDone.length);

        if (current_day == isDone.length) {
            Plan_Days_Coutner.setText("" + isDone.length + " DAYS" + " PLAN COMPLETED");


        } else {
            Plan_Days_Coutner.setText("DAY " + current_day + "/" + isDone.length);
        }


        for (boolean n : isDone) {
            Log.d("Seud", "_" + n);
        }


    }

    private ArrayList<PlanRecycler> generateWorkouts() {
        ArrayList<PlanRecycler> palettes = new ArrayList<>();

        String[] allColumns = new String[]{Dbhelper.PLAN_ID,
                Dbhelper.PLAN_NAME,
                Dbhelper.PLAN_UNDER_TEXT,
                Dbhelper.PLAN_DURATION,
                Dbhelper.PLAN_IMAGE,
                Dbhelper.PLAN_WOKROUTS_ID,
                Dbhelper.PLAN_IS_FINISHED
        };

        Cursor cursor_s = database.query(Dbhelper.TABLE_PLAN_STOCK, allColumns, "_name=\'" + Plan_Name + "\'", null, null, null, null, "1");

        if (cursor_s != null) {
            cursor_s.moveToFirst();
            wokrouts_S = cursor_s.getString(5);
            isDone_S = cursor_s.getString(6);
        }

        try {
            wokrouts_A = wokrouts_S.split("\\s+");
            Log.d("Workouts_name", "" + wokrouts_A);
        } catch (PatternSyntaxException ex) {
        }

        try {
            isDone_A = isDone_S.split("\\s+");
        } catch (PatternSyntaxException ex) {
        }



        Boolean_Generator(isDone_A);

        if (cursor_s.moveToFirst()) {
            do {

                for (int i = 0; i < wokrouts_A.length; i++) {

                    palettes.add(new PlanRecycler(
                            Workout_Name(wokrouts_A[i]), Workout_Name_Holder(wokrouts_A[i]), Tab_Colour.get(i)

                    ));

                }
            } while (cursor_s.moveToNext());
        }
        cursor_s.close();

        return palettes;
    }

    //Workout Name Decider
    public String Workout_Name_Holder(String id_S) {
        String workout_name = "";
        if (id_S.equals("REST")) {
            workout_name = "Rest";
        } else {
            String[] allColumns = new String[]{
                    Dbhelper.WORKOUTS_ID,
                    Dbhelper.WORKOUT_NAME,

            };
            Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");


            if( cursor != null && cursor.moveToFirst() ){
                workout_name = cursor.getString(1);
                cursor.close();
            }

            /*
            if (cursor != null) {
                cursor.moveToFirst();
                //id = cursor.getString(2);
                workout_name = cursor.getString(1);
            }
            cursor.close();
            */
        }
        return workout_name;
    }

    //Workout Name Decider
    public String Workout_Name(String id_S) {
        String workout_name = "";
        String template = "";
        String holder = "";


        if (id_S.equals("REST")) {
            workout_name = "Rest";
        } else {
            String[] allColumns = new String[]{
                    Dbhelper.WORKOUTS_ID,
                    Dbhelper.WORKOUT_NAME,
                    Dbhelper.WORKOUT_TIME

            };
            Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");

            if( cursor != null && cursor.moveToFirst() ){
                Log.d("Cursor_info","not_null");
                if (cursor.getString(1).contains("SPARTAN SPECIALE ADVANCED") || cursor.getString(1).contains("SPARTAN SPECIALE BEGINNER") || cursor.getString(1).contains("TRICEPS SMASHER REPS")) {
                    template = "(reps)";
                } else {
                    template = "(" + cursor.getString(2) + ")";
                }

            }else{
                Log.d("Cursor_info","null");
            }


            try {
                workout_name_shortener = cursor.getString(1).split("\\s+");
                cursor.close();
                int counter = 0;
                for (int i = 0; i < workout_name_shortener.length; i++) {

                    if (workout_name_shortener[i].equals("TIMER") || workout_name_shortener[i].equals("REPS") || workout_name_shortener[i].equals("ADVANCED") || workout_name_shortener[i].equals("BEGINNER") && counter != 0) {
                        break;
                    } else {
                        holder += workout_name_shortener[i] + " ";
                    }
                    counter++;
                }
            }catch (Exception e){
                Log.d("Exception_log",""+e);
            }



            workout_name = holder + template;
            //cursor.close();
        }

        return workout_name;
    }


    public void Boolean_Generator(String[] boolean_S) {

        int counter = 0;

        isDone = new boolean[boolean_S.length];
        for (int i = 0; i < boolean_S.length; i++) {

            if (boolean_S[i].equals("true")) {
                bool_counter++;
                isDone[i] = Boolean.TRUE;

                Tab_Colour.add(getResources().getColor(R.color.siva_3));

            } else {


                if(counter<1){
                    Tab_Colour.add(getResources().getColor(R.color.siva_1));
                }else{
                    Tab_Colour.add(getResources().getColor(R.color.siva_2));
                }
                counter++;
                isDone[i] = Boolean.FALSE;
            }
        }

        for (int i = 0; i < isDone.length; i++) {
            Log.d("bools_a", "" + isDone[i]);
            if (isDone[i] == true) {
                current_day++;
            }
        }

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                back_pressed();
                return true;
            case R.id.action_renew:

                Toast.makeText(this, "Plan renewed", Toast.LENGTH_SHORT).show();

                dbcon.open();

                if(Plan_Name.equals("Newbie")){

                    dbcon.updatePlanStock("Newbie", "UNDER TEXT", "ic_newbie", "7 Days", "5 8 12 REST 7 REST 1", "false false false false false false false");

                }else if(Plan_Name.equals("Alpha 10")){

                    dbcon.updatePlanStock("Alpha 10", "UNDER TEXT", "ic_alphaten", "14 Days", "1 2 3 4 5 6 7 8 9 10", "false false false false false false false false false false");

                }else if(Plan_Name.equals("Alpha V2")){

                    dbcon.updatePlanStock("Alpha V2", "Pro version", "ic_alphav2", "30 Days", "1 3 11 10 13 REST REST 5 4 11 12 8 REST REST 3 7 13 11 REST 13 12 REST REST 6 12 4 1 REST 12 13", "false false false false false false false false false false false false false false false false false false false false false false false false false false false false false false");

                }

                dbcon.close();

                dbcon_l.open();
                dbcon_l.insertData("" + Plan_Name + " Plan", "" + date);
                dbcon_l.close();


                Bundle ExerciseBundle = new Bundle();
                ExerciseBundle.putString("plan_info", Plan_Name);

                Intent i = new Intent(/* FirstActivity.this */
                        getApplicationContext(),
                        PlanAdapter.class);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                i.putExtras(ExerciseBundle);

                startActivity(i);

                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public boolean onCreateOptionsMenu(Menu menu) {

        if (current_day == isDone.length) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.menu_delete, menu);
        }

        return true;
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        back_pressed();

    }


    public void back_pressed() {
        Intent test = new Intent(getApplication(), MainActivity.class);
        test.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(test);
    }

}

Additional Log cat:

Process: com.spartanbodyweightworkouts, PID: 14142 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.spartanbodyweightworkouts/com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460) at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136) at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50) at com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter.Workout_Name(PlanAdapter.java:247) at com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter.generateWorkouts(PlanAdapter.java:174) at com.spartanbodyweightworkouts.tabs.plan.planAdapter.planAdapter.PlanAdapter.onCreate(PlanAdapter.java:109) at android.app.Activity.performCreate(Activity.java:6251) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)  at android.app.ActivityThread.-wrap11(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5417)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

  • Sure i can ,but the problem indicates that the cursor is empty after i add the data to the database ,tho i can use it in another part and the same cursor is not null. –  May 21 '16 at 16:40
  • Well me neither hahahah ,do you have any idea what could it be.Do you see any problems in my code ,any critical parts? –  May 21 '16 at 16:45
  • At which part sorry? –  May 21 '16 at 16:51

2 Answers2

1

Towards the bottom of your code you have commented out the cursor.close;.

Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");

if( cursor != null && cursor.moveToFirst() ){
.../...
workout_name = holder + template;
//cursor.close();

You're closing it too soon and if the try and catch fails you also need to check that the cursor is closed. It's a good idea to keep tidy house keeping of resources in the case of "if" or "try" situations.


public String Workout_Name(String id_S) {
    String workout_name = "";
    String template = "";
    String holder = "";


    if (id_S.equals("REST")) {
        workout_name = "Rest";
    } else {
        String[] allColumns = new String[]{
                Dbhelper.WORKOUTS_ID,
                Dbhelper.WORKOUT_NAME,
                Dbhelper.WORKOUT_TIME

        };
        Cursor cursor = database.query(Dbhelper.TABLE_WORKOUTS_STOCK, allColumns, "_id=\'" + id_S + "\'", null, null, null, null, "1");

        if( cursor != null && cursor.moveToFirst() ){
            Log.d("Cursor_info","not_null");
            if (cursor.getString(1).contains("SPARTAN SPECIALE ADVANCED") || cursor.getString(1).contains("SPARTAN SPECIALE BEGINNER") || cursor.getString(1).contains("TRICEPS SMASHER REPS")) {
                template = "(reps)";
            } else {
                template = "(" + cursor.getString(2) + ")";
            }

        }else{
            Log.d("Cursor_info","null");
        }


        try {
            workout_name_shortener = cursor.getString(1).split("\\s+");
            cursor.close();
            int counter = 0;
            for (int i = 0; i < workout_name_shortener.length; i++) {

                if (workout_name_shortener[i].equals("TIMER") || workout_name_shortener[i].equals("REPS") || workout_name_shortener[i].equals("ADVANCED") || workout_name_shortener[i].equals("BEGINNER") && counter != 0) {
                    break;
                } else {
                    holder += workout_name_shortener[i] + " ";
                }
                counter++;
            }
        }catch (Exception e){
            Log.d("Exception_log",""+e);
        }



        workout_name = holder + template;
        //cursor.close();
    }

    return workout_name;
}

I would recommend using a single instance of your sqlite helper though your application. Have a look here for more details:

Is it OK to have one instance of SQLiteOpenHelper shared by all Activities in an Android application?

Community
  • 1
  • 1
  • The cursor is closed above int counter = 0.The cursor is null when i add data to it.I mean to the database –  May 21 '16 at 17:05
  • Sorry I'm not an native english speaker can you explain this part "Also consider using a single instance of your database helpers to avoid memory leaks" –  May 21 '16 at 17:08
0

The problem is that when i delete all records from the table ,and when i add back the data it switches the id's.But in the plan im requesting the workout on that id that does not exssist.

 dbcon.open();
                dbcon.insertPlanStock("Newbie", "Free", "ic_newbie", "7 Days", "5 8 12 REST 7 REST 1", "false false false false false false false");
                dbcon.close();

The numbers need to be changed to the workout name