使用Cursor.getType()时,连续获取-1的索引

时间:2015-01-28 23:48:21

标签: java android cursor

所以我试图对我自己做一些简单的研究,将其放入游标的不同类型的列中,用于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()可以正常使用相同的代码,并且两者都应该根据基于零的索引返回结果,所以我不明白为什么一个方法不起作用而另一个方法不起作用。

2 个答案:

答案 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时该行没有问题的原因。如您所见,还有一种方法可以将所有列名称作为数组,在上面的示例中使用。

遗憾的是,如果没有值存在,似乎没有办法检索类型。如果我在这里错了,请纠正我。