【问题标题】:Function to update a photo in ContactsContract在 ContactsContract 中更新照片的功能
【发布时间】:2018-05-19 08:49:19
【问题描述】:

我尝试使用获取联系人 id 和图片 uri 的函数更新 ContactsContract 中的照片,但它似乎不起作用(并且我的函数返回 true)。

我真的不明白,因为代码看起来不错。

当联系人已经有照片时,它似乎正在工作......

这是我的功能:

boolean updatePhoto(String idStr, String uri){
        if (uri != null) {
            ArrayList<ContentProviderOperation> ops = new ArrayList<>();

            File imgFile = new File(uri.replace("file://", ""));
            if (imgFile.exists()) {

                Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                myBitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
                ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
                        .withSelection(ContactsContract.Data.CONTACT_ID + " = ?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
                                new String[]{idStr, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE})
                        .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, stream.toByteArray())
                        .build());

                try {
                    getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
                } catch(Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }
        }
        return true;
    }

【问题讨论】:

    标签: android uri android-file contactscontract


    【解决方案1】:

    您的代码仅在联系人已有照片时才有效,因为您使用的是ContentProviderOperation.newUpdate,如果联系人没有照片,您将需要使用ContentProviderOperation.newInsert

    您需要先查询该联系人是否有照片,然后更新/插入新照片:

    private boolean hasPhoto(long contactId) {
        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
        InputStream input = Contacts.openContactPhotoInputStream(getContentResolver(), uri);
        if (input == null) {
            return false;
        }
        Bitmap photo = BitmapFactory.decodeStream(input);
        return (photo != null);
    }
    
    private long getRawId(long contactId) {
        String selection = RawContacts.CONTACT_ID + "='" + contactId + "'";
        Cursor cur = contentResolver.query(RawContacts.CONTENT_URI, new String[]{ RawContacts._ID }, selection, null, null);
        try {
            if (cur.moveToNext()) {
                return cur.getLong(0);
            }
        } finally {
            cur.close();
        }
        return 0;
    }
    
    private boolean updatePhoto(long contactId, String uri) {
        if (uri == null) {
            // do nothing?
            return false;
        }
    
        ContentProviderOperation.Builder builder;
        if (hasPhoto(contactId)) {
            builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
            builder.withSelection(Data.CONTACT_ID + " = ?" + " AND " + Data.MIMETYPE + "=?",
                        new String[]{ String.valueOf(contactId), Photo.CONTENT_ITEM_TYPE});
        } else {
            long rawId = getRawId(contactId);
            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
            builder.withValue(Data.RAW_CONTACT_ID, rawId);
        }
    
        builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
        builder.withValue(Data.IS_SUPER_PRIMARY, 1);
        builder.withValue(Data.IS_PRIMARY, 1);
    
        byte[] photo = getPhotoAsByteArray(uri); // to simplify the answer's code
        builder.withValue(Photo.PHOTO, photo);
    
        try {
            ArrayList<ContentProviderOperation> ops = new ArrayList<>();
            ops.add(builder.build());
            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch(Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    

    【讨论】:

    • 谢谢,但我也有同样的问题。当我的联系人没有照片时,它不起作用。当联系人有照片时,它就可以工作。
    • 我还没有测试 hasPhoto 方法,它是否适合你,它是否进入 newInsert 子句?
    • hasPhoto() 方法工作正常,因此它进入了 newInsert 子句。
    • 当然...您不能将Data 行添加到Contact,您需要指定将包含该数据行的RawContact - 联系人是一个聚合或多个 RawContact,一个 RawContact 是一个或多个 Data 行的聚合
    • 我找到了解决方案:我不必使用 builder.withValue(Data.CONTACT_ID, contactId);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多