当联系人有照片时,无法将BLOB转换为字符串.Android



在我的代码中,我更新了联系人信息,包括姓名、地址、电子邮件和照片。联系的时候没有照片都可以。但是在为联系人分配照片后,我得到android.database.sqlite.SQLiteException:未知错误:无法在每次更新操作上将BLOB转换为字符串。

添加照片到联系人的代码

Bitmap bit =getBitmap();
                    ByteArrayOutputStream streamy = new ByteArrayOutputStream(); 
                    bit.compress(CompressFormat.PNG, 0, streamy); 
                    byte[] photo = streamy.toByteArray();
                    ContentValues values = new ContentValues(); 
                    values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); 
                    values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1); 
                    values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photo); 
                    values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); 
                    try {
                        if (getPhotoUri(rawContactId) != null) {
                            ContactHelper.context.getContentResolver().update(ContactsContract.Data.CONTENT_URI, values,
                                    String.format("%s = ?", ContactsContract.Data.RAW_CONTACT_ID), new String[] {String.format("%d", rawContactId)});
                        } else {
                            ContactHelper.context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

修改联系人姓名的代码

        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        ops.add( ContentProviderOperation.newUpdate( Data.CONTENT_URI )
                .withSelection( Data.RAW_CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'",
                        new String[] { String.valueOf( rawContactId ) } )
                        .withValue( ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getName() )                       
                        .build() );
        try {
            ContentResolver cr = context.getContentResolver();
            cr.applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (Exception e) {
            e.printStackTrace();
        }

ThinkAndroid上有一个很好的小博客条目会告诉你如何做到这一点:http://thinkandroid.wordpress.com/2009/12/30/handling-contact-photos-all-api-levels/

核心部分是:

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

基本上,你不能做的是:

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

这是因为有很多行的RAW_CONTACT_ID = personId(有照片,电话号码,电子邮件等数据行),所以尝试这应该给你一些SQLite异常沿着行的"不能转换BLOB到字符串",这是有意义的,因为在这种情况下,你可能试图更新电话号码行与这些字节,所以它抛出适当的错误。因此,在第一个示例中,首先需要确定哪些行中RAW_CONTACT_ID = personId包含照片的BLOB值,而在第二个查询中,您希望在该行中专门设置该值。注意,有时photoRow可能返回为-1。这基本上告诉我们之前没有人试图设置照片或任何其他信息,所以我们只需要做一个getContentResolver.insert()。为什么这两种情况下的行为不同,我不知道。但是上面的代码可以工作,所以一旦Google发布一些更好的文档,也许我们会发现!