I have an SQLite database in my Android Application. When I do one operation I always get a Finalizing a Cursor that has not been deactivated or closed. Here is the method:
public String getKey(){
net.sqlcipher.database.SQLiteDatabase db = this.getWritableDatabase(Login.authPass);
String selectQuery = "SELECT * FROM " + STABLE;
Cursor cursor = db.rawQuery(selectQuery, null); //This is the line that throws the exception
String s = cursor.getString(1);
cursor.close();
db.close();
return s;
}
It is really frustrating, because I am going to close the Cursor, it just throws an exception before it even gets there. Also I don't get how anything I'm doing on this line is considered finalizing the cursor. Thank you.
Edited to add Logcat:
02-24 12:28:26.522 12756-12765/com.itsmr.dre2k14 E/Cursor﹕ Finalizing a Cursor that has not been deactivated or closed. database = /data/data/com.itsmr.dre2k14/databases/keys.db, table = null, query = SELECT * FROM keys net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here at net.sqlcipher.database.SQLiteCursor.(SQLiteCursor.java:217) at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53) at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1447) at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1416) at com.itsmr.dre_android_clean.KeyTable.getKey(KeyTable.java:41) at com.itsmr.dre_android_clean.Login.noConnectValidate(Login.java:218) at com.itsmr.dre_android_clean.Login.connect(Login.java:97) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at android.view.View$1.onClick(View.java:3964) at android.view.View.performClick(View.java:4640) at android.view.View$PerformClick.run(View.java:19421) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5476) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) at dalvik.system.NativeStart.main(Native Method)
It looks like you should call moveToFirst() to move the cursor to the first row in the database.
Also, just making sure that this is what you intended, calling cursor.getString(1);
will get the second column in the current row, since it is zero based.
http://developer.android.com/reference/android/database/Cursor.html#getString(int)
Also, best practice is to make sure that a cursor is not null before you use it, also use try/catch for database operations.
public String getKey(){
String s = null;
try{
net.sqlcipher.database.SQLiteDatabase db = this.getWritableDatabase(Login.authPass);
String selectQuery = "SELECT * FROM " + STABLE;
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.moveToFirst()){
s = cursor.getString(1);
}
} catch (Exception ex) {
Log.e("MyApp", ex.getMessage());
} finally
{
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return s;
}
This post might be helpful too: cursor.getstring() is getting the wrong field in the database