SQLiteException Unable to convert BLOB to string when contact have photo. Android SQLiteException Unable to convert BLOB to string when contact have photo. Android sqlite sqlite

SQLiteException Unable to convert BLOB to string when contact have photo. Android


There is a nice little blog entry on ThinkAndroid that will show you how to do this:http://thinkandroid.wordpress.com/2009/12/30/handling-contact-photos-all-api-levels/

The core part is this:

public static void setContactPhoto(ContentResolver c, byte[] bytes, long personId) {    ContentValues values = new ContentValues();    int photoRow = -1;    String where = ContactsContract.Data.RAW_CONTACT_ID + " = " + personId + " AND " + ContactsContract.Data.MIMETYPE + "=='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";    Cursor cursor = c.query(ContactsContract.Data.CONTENT_URI, null, where, null, null);    int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);    if (cursor.moveToFirst()) {        photoRow = cursor.getInt(idIdx);    }    cursor.close();    values.put(ContactsContract.Data.RAW_CONTACT_ID, personId);    values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);    values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes);    values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);    if (photoRow >= 0) {        c.update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data._ID + " = " + photoRow, null);    } else {        c.insert(ContactsContract.Data.CONTENT_URI, values);    }}

Basically, what you can’t just do is:

ContentValues values = new ContentValues();values.put(ContactsContract.Data.RAW_CONTACT_ID, personId);values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes.toByteArray());values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE );context.getContentResolver().update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data.RAW_CONTACT_ID + " = " + personId, null);

And that’s because there are many rows where the RAW_CONTACT_ID = personId (there are data rows for the photo, phone numbers, emails, etc) and so trying this should give you some kind of SQLite exception along the lines of “CANNOT CONVERT BLOB TO STRING” and this makes sense as in this case you’re probably trying to update the phone number row with these bytes and so it’s throwing the appropriate error. Thus, in the first example, you need to begin by identifying which of these rows where RAW_CONTACT_ID = personId contains the BLOB value of the photo, and in the second query you want to set it in that row specifically. Now notice that sometimes photoRow may come back as -1. This basically tells us that no one has tried to set the photo or any other information before, and so we simply need to do a getContentResolver.insert(). Now, exactly why the behavior is different in these two cases, I don’t know. But the code above works, so once Google releases some better documentation maybe we’ll find out!