Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cursor.getType() for API Level <11

Tags:

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?

like image 354
jenzz Avatar asked Jul 25 '12 20:07

jenzz


People also ask

What does cursor moveToFirst do?

"A Cursor object, which is positioned before the first entry." Calling moveToFirst() does two things: it allows you to test whether the query returned an empty set (by testing the return value) and it moves the cursor to the first result (when the set is not empty).

What is cursor getColumnIndex?

getColumnIndex(String columnName) Returns the zero-based index for the given column name, or -1 if the column doesn't exist. abstract int. getColumnIndexOrThrow(String columnName) Returns the zero-based index for the given column name, or throws IllegalArgumentException if the column doesn't exist.

Which method is used to get data from cursor?

Once the cursor's position is pointing to a valid row, the columns of the row can be read from the cursor. To read the data, the code in Listing 5.10 uses two methods from the cursor class: Cursor. getColumnIndexOrThrow() and one of the type get() methods from the Cursor class.

What is cursor in Kotlin?

A Cursor implementation that exposes results from a query on a SQLiteDatabase . This interface provides random read-write access to the result set returned by a database query.


1 Answers

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;     } } 

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

like image 99
kassim Avatar answered Oct 06 '22 03:10

kassim