Cursor.getType() for API Level <11
android, android-contentprovider, android-cursor
Solution
You can use this code when cursor is positioned in a valid row:
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";
}
}
Note that Cursor.FIELD_TYPE_* constant values are defined starting from HONEYCOMB.
Problem
I'm querying the CallLog content provider and need to detect the column types. In Honeycomb and newer (API Level 11+) you can get a columns preferred data type by calling the method `Cursor.getType(int columnIndex)` which returns one of the following types: - FIELD_TYPE_NULL (0) - FIELD_TYPE_INTEGER (1) - FIELD_TYPE_FLOAT (2) - FIELD_TYPE_STRING (3) - FIELD_TYPE_BLOB (4) How can I accomplish this on pre-Honeycomb <11 devices? I've tried the following: ``` 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; } } } } } ``` However, no exception is thrown. The data is always casted in the first type you are checking for, in this case getInt(). That means, I get the correct values if the column type is Integer but a 0 for all other types. Why am I not looking in the documentation to check what type is stored? The columns differ depending on the device manufacturer and not all of them are documented, see this question: How to handle manufacturer-dependent differences in ContentProviders? Any ideas?