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:
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?
Expanding on Juan's answer, here is my replacement for the API 11 method Cursor.getType(int i) - for a cursor retuned by an SQL query
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;
}
}