So I've got a database that's got one table, with two fields and one record. I'm using select to retrieve everything from that table, and passing the resulting cursor through this function to try to turn it into a jagged array of strings that will represent the table.
public String[][] cursorTo2dString (Cursor cursor, String[] fields) {
int columnCount = cursor.getColumnCount();
int count = cursor.getCount();
String[][] string2dArray = new String[columnCount][count];
Log.i("StringLengths", count + " & " + columnCount);
Log.i("CursorConts", DatabaseUtils.dumpCursorToString(cursor));
if (cursor.moveToFirst()) {
for (int j=0; j<count && !cursor.isAfterLast(); j++) {
for (int i=0; i<columnCount; i++) {
Log.i("Cursor", cursor.getString(i));
string2dArray[j][i] = cursor.getString(i);
Log.i("StringPoint", string2dArray[j][i]);
}
cursor.moveToNext();
}
}
For reference, whatever appears as the TagIdNo value is currently just a randomly generated number, I'm not actually going to generate this randomly on implementation, I'm just using this for the purposes of testing.
This consistently crashes with the following appearing in the console:
I/StringLengths: 1 & 2
I/CursorConts: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@bd9f011
0 {
TagIdNo=998
TagName=No Parental Permission
}
<<<<<
I/Cursor: 998
I/StringPoint: 998
I/Cursor: No Parental Permission
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.programming.workingpomproject, PID: 23796
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.example.programming.workingpomproject.DbHelper.cursorTo2dString(DbHelper.java:132)
at com.example.programming.workingpomproject.DbHelper.select(DbHelper.java:89)
at com.example.programming.workingpomproject.DbHelper.select(DbHelper.java:92)
at com.example.programming.workingpomproject.MainActivity.testDbMethodGet(MainActivity.java:66)
at com.example.programming.workingpomproject.MainActivity.dbStuff(MainActivity.java:61)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
I've used lots of different methods of taking the contents of the cursor, and no matter what I can only get the first value (the random number in this case) I put into the database. I was wondering if anyone can see why I'm not getting my second value (currently "no parental permission"), and if they could advise me as to how to retrieve it.
Sorry if I've messed up any coding standards; this is my first Android project and my first time in Java but I've been working on this app for a good few months so I'm hoping I'm getting better.
Any and all advice welcome!
EDIT 1: If, as suggested by Giovanni, I swap the columns and rows in the instantiation, I get this instead:
String[][] string2dArray = new String[count][columnCount];
This leads to the following in the console, in the place of the other results:
I/CursorConts: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@45e64e9
0 {
TagIdNo=3259
TagName=No Parental Permission
}
<<<<<
I/Cursor: 3259
I/StringPoint: 3259
I/Cursor: No Parental Permission
I/StringPoint: No Parental Permission
I/MovePos: true & false
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.programming.workingpomproject, PID: 24606
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
Caused by: android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
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.example.programming.workingpomproject.DbHelper.cursorTo2dString(DbHelper.java:155)
at com.example.programming.workingpomproject.DbHelper.select(DbHelper.java:89)
at com.example.programming.workingpomproject.DbHelper.select(DbHelper.java:92)
at com.example.programming.workingpomproject.MainActivity.testDbMethodGet(MainActivity.java:66)
at com.example.programming.workingpomproject.MainActivity.dbStuff(MainActivity.java:61)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
This cursor problem seems to be the root problem, the array index one just being something I messed up in an attempt to avoid the cursor error. Any further help is greatly appreciated!
You got an ArrayIndexOutOfBoundsException
, which means that the array you want to assign in, does not have the correct size you are trying to access. For example, if I create an array like:
String[] array = new String[2];
int i = 3;
String s = array[i];
This will throw an exception, since my array has only place for 2 objects, not 3.
Your array is String[][] string2dArray = new String[columnCount][count];
I think you can fix it by changing it to:
String[][] string2dArray = new String[count][columnCount];
Because here:
for (int j = 0; j < count && !cursor.isAfterLast(); j++) {
for (int i = 0; i < columnCount; i++) {
Log.i("Cursor", cursor.getString(i));
// j should be count size, see the first for loop
string2dArray[j][i] = cursor.getString(i);
Log.i("StringPoint", string2dArray[j][i]);
}
cursor.moveToNext();
}