2013-04-10 50 views
3

在我的代碼中,我更新了聯繫人信息,包括姓名,地址,電子郵件和照片。當聯繫人沒有照片時,一切正常。但爲聯繫人分配照片後,我得到android.database.sqlite.SQLiteException:未知錯誤:無法將BLOB轉換爲字符串在每個更新操作。SQLiteException當聯繫人有照片時,無法將BLOB轉換爲字符串。 Android

我添加圖片的代碼聯繫

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

你的模式是什麼樣的?你對數據庫中的照片有什麼樣的數據類型?我敢打賭它沒有定義或者是一個字符串。 – HalR 2013-04-11 02:38:59

+0

我使用標準的android聯繫人數據庫。文檔說這個datacolumn的類型爲String http://developer.android.com/reference/android/provider/ContactsContract.DataColumns.html#DATA15 – 2013-04-11 06:40:16

回答

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異常「無法轉換BLOB到STRING」,這是有道理的,因爲在這種情況下,你可能試圖用這些字節更新電話號碼行,所以它拋出適當的錯誤。因此,在第一個示例中,您需要首先確定RAW_CONTACT_ID = personId中包含照片BLOB值的這些行中的哪一行,並在第二個查詢中明確指定該行。現在請注意,有時候photoRow可能會返回-1。這基本上告訴我們,沒有人試圖設置照片或任何其他信息,所以我們只需要做一個getContentResolver.insert()。現在,正是爲什麼這兩種情況下的行爲不同,我不知道。但是上面的代碼工作,所以一旦Google發佈了一些更好的文檔,也許我們會發現!

+0

它解決了我的問題thanx :-) – 2013-04-11 17:22:23

+0

非常感謝!偉大的解釋! – 2014-04-08 18:29:36