Search code examples
androidblobandroid-cursor

DatabaseUtils cursorRowToContentValues converts blob to string


I just stumbled upon a problem with Android's DatabaseUtils.cursorRowToContentValues method. In the cursor the blob is correctly stored as a byte array. cursor.getBlob() also returns the correct value. However after using the utils method to convert it, the ContentValues contain a string and calling getAsByteArray returns null, because there is no byte array with that key.

I couldn't find any bug reports for this, but I think this isn't intended?


Solution

  • The cursor is a self filled MatrixCursor.

    That's the problem.

    Here's the code for DatabaseUtils.cursorRowToContentValues():

    710    public static void cursorRowToContentValues(Cursor cursor, ContentValues values) {
    711        AbstractWindowedCursor awc =
    712                (cursor instanceof AbstractWindowedCursor) ? (AbstractWindowedCursor) cursor : null;
    713
    714        String[] columns = cursor.getColumnNames();
    715        int length = columns.length;
    716        for (int i = 0; i < length; i++) {
    717            if (awc != null && awc.isBlob(i)) {
    718                values.put(columns[i], cursor.getBlob(i));
    719            } else {
    720                values.put(columns[i], cursor.getString(i));
    721            }
    722        }
    723    }
    

    Note the use of AbstractWindowedCursor. If the cursor isn't one, everything is treated as strings, including blobs.

    Now, the inheritance graph for MatrixCursor is:

    java.lang.Object
       ↳    android.database.AbstractCursor
           ↳    android.database.MatrixCursor
    

    No AbstractWindowedCursor there.

    Overall, the DatabaseUtils are there only for convenience. If they work for you, fine. If they don't work for you, then you'll have to roll your own util methods.