所以我试图对我自己做一些简单的研究,将其放入游标的不同类型的列中,用于SMS应用程序,但是当试图获取列的类型时,我不断得到-1作为索引。我甚至在第0列硬编码,但由于某些原因它仍然会恢复为-1。任何帮助都会非常感激,我对于正在发生的事情感到茫然。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String tempUri = "content://mms-sms/conversations";
Uri uri = Uri.parse(tempUri);
Cursor c = getContentResolver().query(uri, null, null, null, null);
items = new ArrayList<>();
int length = c.getColumnCount();
for (int i = 0; i < length; i++) {
Log.i(TAG, "" + i);
Items item = new Items();
Log.i(TAG, "" + i);
item.columnName = String.valueOf(c.getType(0));
Log.i(TAG, "" + i);
items.add(item);
}
setListAdapter(new Adapter(this, R.id.list_item, items));
}
调用c.getType()时,for循环中会发生错误。现在它是硬编码的,我仍然得到同样的错误。我已经复制了下面的堆栈跟踪:
01-28 17:40:03.050 29753-29753/com.bluhmann.testapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bluhmann.testapp, PID: 29753
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bluhmann.testapp/com.bluhmann.testapp.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 9
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2336)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2408)
at android.app.ActivityThread.access$900(ActivityThread.java:147)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5273)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 9
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getType(AbstractWindowedCursor.java:130)
at android.database.CursorWrapper.getType(CursorWrapper.java:146)
at com.bluhmann.testapp.MainActivity.onCreate(MainActivity.java:45)
at android.app.Activity.performCreate(Activity.java:5940)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
附:缺少堆栈跟踪的一些底线...它不会进入代码格式,但它是最终的所以我不确定它会有多大用处。如果需要,我会尝试弄清楚如何将其纳入代码。
P.P.S。使用getColumnName()可以正常使用相同的代码,并且两者都应该根据基于零的索引返回结果,所以我不明白为什么一个方法不起作用而另一个方法不起作用。
答案 0 :(得分:0)
在检查数据类型之前,需要将Cursor的索引移动到包含数据的行。例如:
c.moveToFirst();
尽管列名将始终相同 - 这就是getColumnName()
方法按原样工作的原因 - 类型与SQLite中的各个值相关联,因此每列的类型不可用,而是每个值。
答案 1 :(得分:0)
嗯,这是晚了一年,但我认为尝试用更详细的解释来解决这个问题并没有什么坏处。
表使用两个索引。您设置为0的是列索引。但是你没有像Mike M.之前解释的那样设置行索引,因此它保持在-1。
如果您想遍历所有字段,我建议使用包含do{}while();
循环的for(item:list)
循环:
String[] colNames = cursor.getColumnNames();
int colIndex;
int rowIndex;
if (cursor.moveToFirst()) { // sets the cursor position / row index to 0
do {
rowIndex = cursor.getPosition();
for ( String colName : colNames ) {
colIndex = cursor.getColumnIndex(colName);
Log.i(TAG,
"Column Name: " + colName +
"Current Row: " + Integer.toString(rowIndex) +
"\nType = " + Integer.toString(cursor.getType(colIndex)) /*+
"\nValue" + cursor.getString(index)
or cursor.getInt(index)
or cursor.getFloat(index)
or cursor.getLong(index)
etc.
You can compare the type from cursor.getType(index)
with the Cursor.FIELD_TYPE_* constants
*/);
}
} while (cursor.moveToNext());
}
这样,您始终可以使用当前列的名称加上当前行的索引,从而可以在调试时识别您正在查看的确切字段。
方法moveToFirst()
和moveToNext()
返回布尔值:如果行存在则为true,否则为false。
getColumnName(int)
不需要行索引,因为它只包含列的名称,这就是使用列索引0时该行没有问题的原因。如您所见,还有一种方法可以将所有列名称作为数组,在上面的示例中使用。
遗憾的是,如果没有值存在,似乎没有办法检索类型。如果我在这里错了,请纠正我。