API Level <11的Cursor.getType()

jen*_*nzz 24 android android-contentprovider android-cursor

我正在查询CallLog内容提供程序,需要检测列类型.

在Honeycomb和更新版本(API Level 11+)中,您可以通过调用Cursor.getType(int columnIndex)返回以下类型之一的方法获取列首选数据类型:

  • FIELD_TYPE_NULL(0)
  • FIELD_TYPE_INTEGER(1)
  • FIELD_TYPE_FLOAT(2)
  • FIELD_TYPE_STRING(3)
  • FIELD_TYPE_BLOB(4)

如何在Honeycomb <11设备上实现这一目标?

我尝试过以下方法:

for ( int i = 0; i < cursor.getColumnCount(); i++ ) {    

    int columnType = -1;
    try {
        cursor.getInt( i );
        columnType = Cursor.FIELD_TYPE_INTEGER;

    } catch ( Exception ignore ) {

        try {
            cursor.getString( i );
            columnType = Cursor.FIELD_TYPE_STRING;

        } catch ( Exception ignore1 ) {

            try {
                cursor.getFloat( i );
                columnType = Cursor.FIELD_TYPE_FLOAT;

            } catch ( Exception ignore2 ) {

                try {                                             
                  cursor.getBlob( i );
                  columnType = Cursor.FIELD_TYPE_BLOB;

                } catch ( Exception ignore3 ) {

                     columnType = Cursor.FIELD_TYPE_NULL;
                }
           }
       }
   }

}
Run Code Online (Sandbox Code Playgroud)

但是,不会抛出任何异常.数据始终以您要检查的第一种类型进行转换,在本例中为getInt().这意味着,如果列类型为Integer,则获取正确的值,而对于所有其他类型,我获取0.

为什么我不查看文档来检查存储的类型?这些列因设备制造商而异,并非所有列都有记录,请参阅此问题:如何处理ContentProviders中与制造商相关的差异?

有任何想法吗?

kas*_*sim 12

扩展Juan的答案,这里是我对API 11方法Cursor.getType(int i)的替代 - 对于由SQL查询重新调整的游标

public class DbCompat {

    protected static final int FIELD_TYPE_BLOB = 4;
    protected static final int FIELD_TYPE_FLOAT = 2;
    protected static final int FIELD_TYPE_INTEGER = 1;
    protected static final int FIELD_TYPE_NULL = 0;
    protected static final int FIELD_TYPE_STRING = 3;

    static int getType(Cursor cursor, int i) throws Exception {
        SQLiteCursor sqLiteCursor = (SQLiteCursor) cursor;
        CursorWindow cursorWindow = sqLiteCursor.getWindow();
        int pos = cursor.getPosition();
        int type = -1;
        if (cursorWindow.isNull(pos, i)) {
            type = FIELD_TYPE_NULL;
        } else if (cursorWindow.isLong(pos, i)) {
            type = FIELD_TYPE_INTEGER;
        } else if (cursorWindow.isFloat(pos, i)) {
            type = FIELD_TYPE_FLOAT;
        } else if (cursorWindow.isString(pos, i)) {
            type = FIELD_TYPE_STRING;
        } else if (cursorWindow.isBlob(pos, i)) {
            type = FIELD_TYPE_BLOB;
        }

        return type;
    }
}
Run Code Online (Sandbox Code Playgroud)

要点:https://gist.github.com/kassim/c340cbfc5243db3a4826


Jua*_*hez 10

当光标位于有效行中时,您可以使用此代码:

CursorWrapper cw = (CursorWrapper)cursor;

Class<?> cursorWrapper = CursorWrapper.class;
Field mCursor = cursorWrapper.getDeclaredField("mCursor");
mCursor.setAccessible(true);
AbstractWindowedCursor abstractWindowedCursor = (AbstractWindowedCursor)mCursor.get(cw);
CursorWindow cursorWindow = abstractWindowedCursor.getWindow();
int pos = abstractWindowedCursor.getPosition();
for ( int i = 0; i < cursor.getColumnCount(); i++ ) {
    String type = null;
    if (cursorWindow.isNull(pos, i)) {
        type = "Cursor.FIELD_TYPE_NULL";
    } else if (cursorWindow.isLong(pos, i)) {
        type = "Cursor.FIELD_TYPE_INTEGER";
    } else if (cursorWindow.isFloat(pos, i)) {
        type = "Cursor.FIELD_TYPE_FLOAT";
    } else if (cursorWindow.isString(pos, i)) {
        type = "Cursor.FIELD_TYPE_STRING";
    } else if (cursorWindow.isBlob(pos, i)) {
        type = "Cursor.FIELD_TYPE_BLOB";
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,Cursor.FIELD_TYPE_*常量值是从HONEYCOMB开始定义的.