3

私のコードでは、名前、住所、電子メール、写真などの連絡先情報を更新しています。連絡がない場合でも写真はOKです。しかし、連絡先に写真を割り当てた後、android.database.sqlite.SQLiteException: unknown error: Unable to convert BLOB to string on each update operation を取得します。

連絡先に写真を追加するための私のコード

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

1 に答える 1

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 (写真、電話番号、電子メールなどのデータ行がある) である行が多数あるためです。これを試みると、「CANNOT CONVERT BLOB TO STRING」の行に沿って何らかの SQLite 例外が発生するはずです。この場合、おそらくこれらのバイトで電話番号の行を更新しようとしており、適切なエラーがスローされているため、これは理にかなっています。したがって、最初の例では、RAW_CONTACT_ID = personId に写真の BLOB 値が含まれている行を特定することから始める必要があり、2 番目のクエリでは、その行に具体的に設定する必要があります。ここで、photoRow が -1 として返される場合があることに注意してください。これは基本的に、誰も写真やその他の情報を設定しようとしたことがないため、getContentResolver.insert() を実行するだけでよいことを示しています。今、これら 2 つのケースで動作が異なる正確な理由はわかりません。しかし、上記のコードは機能するので、Google がより良いドキュメントをリリースしたら、それがわかるかもしれません!

于 2013-04-11T13:24:47.663 に答える