Cannot close a cursor even though its closed
<p>I have written a class that allows my users to update their appointment details.</p>

<p>Within the 'onCreate' method I am populating a number of editTexts and setting a date picker along time picker and a toggle button from my database. Populating these items works fine. My issue is that as soon as I adjust the preset 'date' value of my datapicker, I'm getting a:</p>

<p>'Releasing statement in a finializer' error.</p>

<p>This is resulting in my try catches being triggered and the edit failing to update.
Here's the full LogCat Error:</p>

<pre><code>02-07 17:27:03.741: W/SQLiteCompiledSql(278): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: SELECT _id, app_name, app_type, app_time, app_date, app_comments FROM appointmentsTable WHERE _id=2
02-07 17:27:03.741: W/SQLiteCompiledSql(278): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteCompiledSql.&lt;init&gt;(SQLiteCompiledSql.java:62)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteProgram.&lt;init&gt;(SQLiteProgram.java:80)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteQuery.&lt;init&gt;(SQLiteQuery.java:46)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at com.example.flybase2.DBHandlerApp.getComments(DBHandlerApp.java:355)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at com.example.flybase2.AppointmentEditChanges.onCreate(AppointmentEditChanges.java:178)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.os.Handler.dispatchMessage(Handler.java:99)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.os.Looper.loop(Looper.java:123)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at android.app.ActivityThread.main(ActivityThread.java:4627)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at java.lang.reflect.Method.invokeNative(Native Method)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at java.lang.reflect.Method.invoke(Method.java:521)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-07 17:27:03.741: W/SQLiteCompiledSql(278):   at dalvik.system.NativeStart.main(Native Method)
02-07 17:27:03.772: E/Database(278): close() was never explicitly called on database '/data/data/com.example.flybase2/databases/app_name' 
02-07 17:27:03.772: E/Database(278): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-07 17:27:03.772: E/Database(278):    at android.database.sqlite.SQLiteDatabase.&lt;init&gt;(SQLiteDatabase.java:1810)
02-07 17:27:03.772: E/Database(278):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
02-07 17:27:03.772: E/Database(278):    at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
02-07 17:27:03.772: E/Database(278):    at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
02-07 17:27:03.772: E/Database(278):    at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
02-07 17:27:03.772: E/Database(278):    at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
02-07 17:27:03.772: E/Database(278):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
02-07 17:27:03.772: E/Database(278):    at com.example.flybase2.DBHandlerApp.open(DBHandlerApp.java:157)
02-07 17:27:03.772: E/Database(278):    at com.example.flybase2.AppointmentEditChanges.onCreate(AppointmentEditChanges.java:176)
02-07 17:27:03.772: E/Database(278):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-07 17:27:03.772: E/Database(278):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-07 17:27:03.772: E/Database(278):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-07 17:27:03.772: E/Database(278):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-07 17:27:03.772: E/Database(278):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-07 17:27:03.772: E/Database(278):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-07 17:27:03.772: E/Database(278):    at android.os.Looper.loop(Looper.java:123)
02-07 17:27:03.772: E/Database(278):    at android.app.ActivityThread.main(ActivityThread.java:4627)
02-07 17:27:03.772: E/Database(278):    at java.lang.reflect.Method.invokeNative(Native Method)
02-07 17:27:03.772: E/Database(278):    at java.lang.reflect.Method.invoke(Method.java:521)
02-07 17:27:03.772: E/Database(278):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-07 17:27:03.772: E/Database(278):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-07 17:27:03.772: E/Database(278):    at dalvik.system.NativeStart.main(Native Method)
02-07 17:27:03.811: W/SQLiteCompiledSql(278):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
</code></pre>

<p>This is my current 'AppointmentEditChanges' class:</p>

<pre><code>protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.editappointment);

    editAppointName = (EditText) findViewById(R.id.inputNewAppName);
    editTime = (Spinner) findViewById(R.id.spinner1);
    editTimePicker = (TimePicker) findViewById(R.id.timePickerEdit);
    editDatePicker = (DatePicker) findViewById(R.id.datePickerEdit);
    editCommentsApp = (EditText) findViewById(R.id.inputNewComm);
    editToggle = (ToggleButton) findViewById(R.id.toggleButton1);
    editUpdateApp = (Button) findViewById(R.id.btnChangesApp);
    editDelApp = (Button) findViewById(R.id.btnDeleteApp);




    Bundle extras = getIntent().getExtras(); 
    if (extras != null) {
        passedID = extras.getLong("passedID"); 
    }


    DBHandlerApp getName = new DBHandlerApp(this, null, null);

    getName.open();
    String nameReturned = getName.getNameEditForAppointment(passedID);
    String typeReturned = getName.getAppointTypeEditForAppointment(passedID);


    editAppointName.setText(nameReturned);


    List&lt;String&gt; list = new ArrayList&lt;String&gt;();
    list.add("-");
    list.add("Medical");
    list.add("Business");
    list.add("Family");
    list.add("Other");
    ArrayAdapter&lt;String&gt; dataAdapter = new ArrayAdapter&lt;String&gt;(this, android.R.layout.simple_spinner_item, list);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    editTime.setAdapter(dataAdapter);


    for(int a = 0; a &lt; list.size(); a ++)
    {


    if(typeReturned.equals(list.get(a)))
    {

        editTime.setSelection(a);


    }

    }


    DBHandlerApp timeToEdit= new DBHandlerApp(this, null, null);
    timeToEdit.open();
    String returnedTime = timeToEdit.getTime(passedID);


     SimpleDateFormat newFormat = new SimpleDateFormat("HH:mm");
     try 
    {
    cake = newFormat.parse(returnedTime);
    } catch (ParseException e)
    {

        e.printStackTrace();
    }     






     Calendar cal = Calendar.getInstance();
     cal.setTime(cake);
     editTimePicker.setCurrentHour(cal.get( Calendar.HOUR_OF_DAY ));
     editTimePicker.setCurrentMinute(cal.get( Calendar.MINUTE ));



     DBHandlerApp dateToEdit= new DBHandlerApp(this, null, null);
        dateToEdit.open();
        String returnedDate = dateToEdit.dateToEdit(passedID);
        dateToEdit.close();



        SimpleDateFormat newFormatDate = new SimpleDateFormat("dd-MMM-yyyy");



         try 
        {
        dateToEditApp = newFormatDate.parse(returnedDate);
        } catch (ParseException e)
        {

            e.printStackTrace();
        }     

         Calendar calDate = Calendar.getInstance();

         calDate.setTime(dateToEditApp);

         int year = calDate.get(Calendar.YEAR);
         int monthOfYear = calDate.get(Calendar.MONTH);
         int dayOfMonth = calDate.get(Calendar.DAY_OF_MONTH);

         editDatePicker.init(year, monthOfYear, dayOfMonth, null);


         DBHandlerApp commentsApp = new DBHandlerApp(this, null, null);

         commentsApp.open();

        String returnedComment = commentsApp.getComments(passedID);

         editCommentsApp.setText(returnedComment);
         typeToSet =  editTime.getSelectedItem().toString();

         DBHandlerApp editAlarm = new DBHandlerApp(this, null, null);

         editAlarm.open();

        Integer alarmEditResult =  editAlarm.checkAlarmStatus(passedID);


         if(alarmEditResult == 1)
         {

             setTog = true;

             editToggle.setChecked(setTog);


         }

         else
         {

             setTog = false;

             editToggle.setChecked(setTog);

         }
         editUpdateApp.setOnClickListener(this);
         editDelApp.setOnClickListener(this);






            editToggle.setChecked(setTog);


            editToggle.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {

                if (editToggle.isChecked()) {
                setTog = true;
                editToggle.setChecked(setTog);

                } else {

                    setTog = false;
                    editToggle.setChecked(setTog);

                }
                }
                });



}




@Override
public void onClick(View editChoice) {
    switch(editChoice.getId()){

    case (R.id.btnChangesApp):


        if(setTog != false)
            try{

            Integer dobMonth = editDatePicker.getMonth();
            Integer dobYear =  editDatePicker.getYear();
            Integer dobDate =  editDatePicker.getDayOfMonth();

           Integer dobHour = editTimePicker.getCurrentHour();
           Integer dobMinute = editTimePicker.getCurrentMinute();



           String timeToSet;
           Format formatter;
           Calendar calendar = Calendar.getInstance();
           calendar.set(Calendar.HOUR_OF_DAY, setTime.getCurrentHour());
           calendar.set(Calendar.MINUTE, setTime.getCurrentMinute());

           formatter = new SimpleDateFormat("HH:mm");
           timeToSet = formatter.format(calendar.getTime());

           ////////////////////////////////////////////////
           String dateToSet;
           Format formatterDate;
           Calendar calendarDate = Calendar.getInstance();
           calendarDate.set(Calendar.YEAR, editDatePicker.getYear());
           calendarDate.set(Calendar.MONTH, editDatePicker.getMonth());
           calendarDate.set(Calendar.DAY_OF_MONTH, editDatePicker.getDayOfMonth());

           formatterDate = new SimpleDateFormat("dd-MMM-yyyy");
           dateToSet = formatterDate.format(calendar.getTime());
           //////////////////////////////////////////////////


            Date setDate = new Date(dobYear - 1900, dobMonth, dobDate);


            //Time timeToSet = new Time();
            //timeToSet.set(0, dobMinute, dobHour);


            alarmToSet =  true;


            DBHandlerApp updateApp = new DBHandlerApp(this, null, null);
             updateApp.open();
            updateApp.updateAppDetails(passedID, updateNameAppoint, updateCommsAppoint, timeToSet, dateToSet, typeToSet, alarmToSet);

        AlarmManager dateSet = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, DateAlarm.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
        dateSet.set(AlarmManager.RTC_WAKEUP, setDate.getTime(), pendingIntent); 
            }


            catch (Exception e)
            {
                check = false;

                Dialog d = new Dialog(this);
                d.setTitle("Appointment Failed To Be Updated 1");
                TextView txt = new TextView(this);
                txt.setText("Fail");
                d.setContentView(txt);
                d.show();
            }
            finally
            {
                if(check = true);
                {

                    Dialog e = new Dialog(this);
                    e.setTitle("Appointment Has Been Updated.");
                    TextView txt = new TextView(this);
                    txt.setText("Success");
                    e.setContentView(txt);
                    e.show();
                }

            }

            else if(setTog == false)
            {

                alarmToSet = false;
                try
                {
                DBHandlerApp createAppFalse = new DBHandlerApp(this, null, null);

                Integer dobMonth = editDatePicker.getMonth();
                Integer dobYear = editDatePicker.getYear();
                Integer dobDate = editDatePicker.getDayOfMonth();

                Integer dobHour = editTimePicker.getCurrentHour();
                Integer dobMinute = editTimePicker.getCurrentMinute();

                Date setDate = new Date(dobYear - 1900, dobMonth, dobDate);

                //Time timeToSet = new Time();
                //timeToSet.set(0, dobMinute, dobHour);
                   String timeToSet;
                   Format formatter;
                   Calendar calendar = Calendar.getInstance();
                   calendar.set(Calendar.HOUR_OF_DAY, setTime.getCurrentHour());
                   calendar.set(Calendar.MINUTE, setTime.getCurrentMinute());

                   formatter = new SimpleDateFormat("HH:mm");
                   timeToSet = formatter.format(calendar.getTime());



                   ////////////////////////////////////////////////
                   String dateToSeta;
                   Format formatterDatea;
                   Calendar calendarDate = Calendar.getInstance();
                   calendarDate.set(Calendar.YEAR, editDatePicker.getYear());
                   calendarDate.set(Calendar.MONTH, editDatePicker.getMonth());
                   calendarDate.set(Calendar.DAY_OF_MONTH, editDatePicker.getDayOfMonth());


                   formatterDatea = new SimpleDateFormat("dd-MMM-yyyy");
                   dateToSeta =   formatterDatea.format(calendar.getTime());
                   //////////////////////////////////////////////////

                   DBHandlerApp updateApp = new DBHandlerApp(this, null, null);
                   updateApp.open();
                    updateApp.updateAppDetails(passedID, updateNameAppoint, typeToSet, timeToSet,  dateToSeta, updateCommsAppoint, alarmToSet);

                }
                catch (Exception e)
                {
                    check = false;

                    Dialog d = new Dialog(this);
                    d.setTitle("Appointment Failed To Be Added 2");
                    TextView txt = new TextView(this);
                    txt.setText("Fail");
                    d.setContentView(txt);
                    d.show();
                }
                finally
                {
                    if(check = true);
                    {

                        Dialog e = new Dialog(this);
                        e.setTitle("New Appointment Added.");
                        TextView txt = new TextView(this);
                        txt.setText("Success");
                        e.setContentView(txt);
                        e.show();
                    }
                    finish();
                }

        }



    break;

    case (R.id.btnDeleteApp):

    DBHandlerApp deleteApp = new DBHandlerApp(this, null, null);
    deleteApp.open();
    deleteApp.deleteAppointment(passedID);
    deleteApp.close();


    break;
}

}
}
</code></pre>

<p>And these are the methods I am using from my database Handler class. As far As I can see, I am closing the cursors correctly?</p>

<pre><code>public String getNameEditForAppointment(Long passedID) {

        String [] columns = new String[]{KEY_ROWAPPID, KEY_NAMEAPP, KEY_TYPEAPP, KEY_TIMEAPP, KEY_DATEAPP, KEY_COMMENTAPP};
        Cursor c = ourDatabase.query(DATABASE_TABLEAPP, columns, KEY_ROWAPPID + "=" + passedID, null, null, null, null);
        if(c != null)
        {
            if(c.getCount() &gt; 0 &amp;&amp; c.moveToFirst())

            {
                c.moveToFirst();
                String name = c.getString(1);
                c.close();
                return name;

            }
        }
        c.close();
        return null;

    }

    public String getAppointTypeEditForAppointment(Long passedID) {
        String [] columns = new String[]{KEY_ROWAPPID, KEY_NAMEAPP, KEY_TYPEAPP, KEY_TIMEAPP, KEY_DATEAPP, KEY_COMMENTAPP};
        Cursor c = ourDatabase.query(DATABASE_TABLEAPP, columns, KEY_ROWAPPID + "=" + passedID, null, null, null, null);
        if(c != null)
        {
            if(c.getCount() &gt; 0 &amp;&amp; c.moveToFirst())

            {
                c.moveToFirst();
                String name = c.getString(2);
                c.close();
                return name;

            }
        }
        c.close();
        return null;

    }

    public String getTime(Long passedID) {

        String [] columns = new String[]{KEY_ROWAPPID, KEY_NAMEAPP, KEY_TYPEAPP, KEY_TIMEAPP, KEY_DATEAPP, KEY_COMMENTAPP};
        Cursor c = ourDatabase.query(DATABASE_TABLEAPP, columns, KEY_ROWAPPID + "=" + passedID, null, null, null, null);
         if(c != null)
            {
                if(c.getCount() &gt; 0 &amp;&amp; c.moveToFirst())

                {
                    c.moveToFirst();
                    String name = c.getString(3);
                    c.close();
                    return name;
                }
            }
            c.close();
            return null;

    }

    public String dateToEdit(Long passedID) {

        String [] columns = new String[]{KEY_ROWAPPID, KEY_NAMEAPP, KEY_TYPEAPP, KEY_TIMEAPP, KEY_DATEAPP, KEY_COMMENTAPP};
        Cursor c = ourDatabase.query(DATABASE_TABLEAPP, columns, KEY_ROWAPPID + "=" + passedID, null, null, null, null);
         if(c != null)
            {
                if(c.getCount() &gt; 0 &amp;&amp; c.moveToFirst())

                {
                    c.moveToFirst();
                    String date = c.getString(4);
                    c.close();
                    return date;
                }
            }
            c.close();
            return null;

    }

    public String getComments(Long passedID) {
        String [] columns = new String[]{KEY_ROWAPPID, KEY_NAMEAPP, KEY_TYPEAPP, KEY_TIMEAPP, KEY_DATEAPP, KEY_COMMENTAPP};
        Cursor c = ourDatabase.query(DATABASE_TABLEAPP, columns, KEY_ROWAPPID + "=" + passedID, null, null, null, null);
         if(c != null &amp;&amp; c.getCount() &gt; 0)
        {
        c.moveToFirst();
        String comment = c.getString(5);

        if(comment.equals(""))
        {
            String noComm = "No Set Comment.";
            c.close();
            return noComm;
        }
        else
        {
            c.close();
            return comment;

        }


    }
         c.close();
         return null;
    }

    public Integer checkAlarmStatus(Long passedID) {

        String [] columns = new String[]{KEY_ROWAPPID, KEY_NAMEAPP, KEY_TYPEAPP, KEY_TIMEAPP, KEY_DATEAPP, KEY_COMMENTAPP, KEY_ALARM};
        Cursor c = ourDatabase.query(DATABASE_TABLEAPP, columns, KEY_ROWAPPID + "=" + passedID, null, null, null, null);    
         if(c != null)
                {
                    if(c.getCount() &gt; 0 &amp;&amp; c.moveToFirst())

                    {
                        c.moveToFirst();
                        int res = c.getInt(6);
                        c.close();
                        return res;
                    }
                }
                c.close();
                return null;



}
</code></pre>
