在我的代码中,我更新了联系信息,包括姓名,地址,电子邮件和照片。当联系人没有照片时都可以。但在为联系人分配照片后,我得到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();
}
答案 0 :(得分:4)
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异常,就像“CAN NOT CONVERT” BLOB TO STRING“这是有道理的,因为在这种情况下,您可能正在尝试使用这些字节更新电话号码行,因此它会抛出相应的错误。因此,在第一个示例中,您需要首先确定哪些行RAW_CONTACT_ID = personId包含照片的BLOB值,然后在第二个查询中要特别设置该行。现在请注意,有时photoRow可能会返回-1。这基本上告诉我们之前没有人尝试过设置照片或任何其他信息,所以我们只需要做一个getContentResolver.insert()。现在,确切地说,为什么这两种情况的行为不同,我不知道。但上面的代码有效,所以一旦谷歌发布了一些更好的文档,我们就会发现!