【问题标题】:Android - Update a contactAndroid - 更新联系人
【发布时间】:2012-03-28 12:43:31
【问题描述】:

我正在尝试直接从我的应用更新我的电话簿联系人。我可以添加和删除联系人,但更新什么也没做!

插入后或抓取联系人时,我会收集 CONTACT_ID(又名 _ID)。

这是我的更新代码:

public void update(Relation r)
{
    Log.e("", ""+r.getBook_id());
    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

    Builder builder = ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI);
    builder.withValue(RawContacts.ACCOUNT_TYPE, null);
    builder.withValue(RawContacts.ACCOUNT_NAME, null);
    ops.add(builder.build());

    // Name
    builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
    builder.withSelection(ContactsContract.Data._ID,  new String[]{String.valueOf(r.getBook_id())});
    builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
    builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, r.getFirstName()+ " " +r.getLastName());
    ops.add(builder.build());

    // Number
    builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
    builder.withSelection(ContactsContract.Data._ID,  new String[]{String.valueOf(r.getBook_id())});
    builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
    builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, r.getNumber());
    builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
    ops.add(builder.build());

    // Picture
    try
    {
        Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(r.getPhoto()));
        ByteArrayOutputStream image = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
        builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
        builder.withSelection(ContactsContract.Data._ID,  new String[]{String.valueOf(r.getBook_id())});
        builder.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
        builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
        ops.add(builder.build());
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    // Update
    try
    {
        context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

r.getBook_id() 给了我当前联系人的 _ID 值。 r.getFirstName()r.getLastName() 给我联系人的姓名。 r.getPhoto() 给了我他的照片 uri。 最后r.getNumber() 给了我他的电话号码。

Log 行给了我一个正确的 _ID 值,我认为问题不在于这里。 我是不是做错了什么?

谢谢。

问候。

V.


完整源代码:

/**
 * Uses the Contacts API to load contacts from the phonebook.
 * 
 */
public class ContactUtils
{
    static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.STARRED,
        ContactsContract.Contacts.TIMES_CONTACTED,
        ContactsContract.Contacts.CONTACT_PRESENCE,
        ContactsContract.Contacts.PHOTO_ID,
        ContactsContract.Contacts.LOOKUP_KEY,
        ContactsContract.Contacts.HAS_PHONE_NUMBER,
    };

    private Activity context;

    static final int CARD_LIMIT = 50;

    /**
     * Constructor
     *
     * @version 1.0
     * @since 2012-03-28
     * @param context Context of the running activity
    */
    public ContactUtils(Activity context)
    {
        super();
        this.context = context;
    }

    /**
     * Returns a list of all the contacts in the phonebook
     *
     * @version 1.0
     * @since 2012-03-28
     * @return Returns a list of all the contacts in the phonebook
    */
    public ArrayList<Relation> loadContacts()
    {
        String select = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Contacts.HAS_PHONE_NUMBER + " == 1))";
        Cursor c = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_SUMMARY_PROJECTION, select, null, ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
        context.startManagingCursor(c);

        ArrayList<Relation> cList = new ArrayList<Relation>();
        int a = 0;
        Relation relation;
        while (c.moveToNext() && a<CARD_LIMIT)
        {
            relation = new Relation();
            relation.setBook_id(new Integer(c.getString(0)).intValue());

            String[] name_splitted = c.getString(1).split(" ");
            relation.setFirstName(name_splitted[0]);
            if (name_splitted.length > 1) relation.setLastName(name_splitted[1]);

            ArrayList<String> numbers = getPhoneNumbers(c.getString(0));
            relation.setNumber(numbers.size() > 0 ? numbers.get(0) : "" );

            relation.setConcept("Any");
            relation.setPhoto(loadContactPhoto(c) == null ? "android.resource://com.orange.rd.kramer/drawable/default_photo" : loadContactPhoto(c));

            cList.add(relation);
            a++;
        }
        c.close();
        return cList;
    }

    /**
     * Returns an uri pointing to the contact's photo
     *
     * @version 1.0
     * @since 2012-03-28
     * @param cursor Cursor on a specific contact
     * @return Returns an uri pointing to the contact's photo
    */
    private String loadContactPhoto(Cursor cursor)
    {
        if (cursor.getString(5) != null)
        {
            Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, cursor.getInt(0));           
            return Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY).toString();
        }
        return null;
    }

    /**
     * Returns a list of all phone numbers that belong to the given contact
     *
     * @version 1.0
     * @since 2012-03-28
     * @param id Id of the given contact
     * @return Returns a list of all phone numbers that belong to the given contact
    */
    private ArrayList<String> getPhoneNumbers(String id)
    {
        ArrayList<String> phones = new ArrayList<String>();

        Cursor pCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
        while (pCur.moveToNext())
        {
            phones.add(pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
        } 
        pCur.close();
        return(phones);
    }

    /**
     * Inserts the given relation into the stock phone book
     *
     * @version 1.0
     * @since 2012-03-28
     * @param r Relation to be added into the stock phone book
    */
    public void insert(Relation r)
    {
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        int rawContactInsertIndex = ops.size();

        Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI);
        builder.withValue(RawContacts.ACCOUNT_TYPE, null);
        builder.withValue(RawContacts.ACCOUNT_NAME, null);
        ops.add(builder.build());

        // Name
        builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
        builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex);
        builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, r.getFirstName().replace(" ", "-")+ " " +r.getLastName().replace(" ", "-"));
        ops.add(builder.build());

        // Number
        builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
        builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex);
        builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, r.getNumber());
        builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
        ops.add(builder.build());

        // Picture
        try
        {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(r.getPhoto()));
            ByteArrayOutputStream image = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
            builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
            builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex);
            builder.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
            builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
            ops.add(builder.build());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        // Add the new contact
        try
        {
            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        String select = "(" + ContactsContract.Contacts.DISPLAY_NAME + " == \"" +r.getFirstName().replace(" ", "-")+ " " +r.getLastName().replace(" ", "-")+ "\" )";
        Cursor c = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_SUMMARY_PROJECTION, select, null, ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
        context.startManagingCursor(c);

        if (c.moveToNext())
        {
            r.setBook_id(new Integer(c.getString(0)).intValue());
        }
        else
        {
            r.setBook_id(-1);
        }
    }

    /**
     * Updates the given relation in the stock phone book
     *
     * @version 1.0
     * @since 2012-03-28
     * @param r Relation to be updated in the stock phone book
    */
    public void update(Relation r)
    {
        Log.e("", ""+r.getBook_id());
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

        Builder builder = ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI);
        builder.withValue(RawContacts.ACCOUNT_TYPE, null);
        builder.withValue(RawContacts.ACCOUNT_NAME, null);
        ops.add(builder.build());

        // Name
        builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
        builder.withSelection(ContactsContract.Data._ID,  new String[]{String.valueOf(r.getBook_id())});
        builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, r.getFirstName().replace(" ", "-")+ " " +r.getLastName().replace(" ", "-"));
        ops.add(builder.build());

        // Number
        builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
        builder.withSelection(ContactsContract.Data._ID,  new String[]{String.valueOf(r.getBook_id())});
        builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, r.getNumber());
        builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
        ops.add(builder.build());

        // Picture
        try
        {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(r.getPhoto()));
            ByteArrayOutputStream image = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
            builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
            builder.withSelection(ContactsContract.Data._ID,  new String[]{String.valueOf(r.getBook_id())});
            builder.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
            builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
            ops.add(builder.build());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        // Update
        try
        {
            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * Deletes the given relation from the stock phone book
     *
     * @version 1.0
     * @since 2012-03-28
     * @param r Relation to be removed from the stock phone book
    */
    public void delete(Relation r)
    {
        Cursor pCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{""+r.getBook_id()}, null);
        while (pCur.moveToNext())
        {
            String lookupKey = pCur.getString(pCur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
            Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
            context.getContentResolver().delete(uri, null, null);
        }
    }
}

【问题讨论】:

    标签: java android


    【解决方案1】:

    终于找到了更新联系人的方法,下面是更新方法的代码:

        public void update()
        {       
            int id = 1;
            String firstname = "Contact's first name";
            String lastname = "Last name";
            String number = "000 000 000";
            String photo_uri = "android.resource://com.my.package/drawable/default_photo";
    
            ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
    
            // Name
            Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
            builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE});
            builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastname);
            builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstname);
            ops.add(builder.build());
    
            // Number
            builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
            builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?"+ " AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_HOME)});
            builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number);
            ops.add(builder.build());
    
    
            // Picture
            try
            {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.parse(photo_uri));
                ByteArrayOutputStream image = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
    
                builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
                builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
                builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
                ops.add(builder.build());
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    
            // Update
            try
            {
                getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    

    id 字段是您在数据库中插入新联系人时返回的原始联系人 ID。下面是获取这个id的代码:

        ContentProviderResult[] res;
        try
        {
            res = KramerApplication.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
            if (res != null && res[0] != null)
            {
                String uri = res[0].uri.getPath().substring(14);
                r.setBook_id( new Integer(uri).intValue() );
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    

    如果您想了解有关如何插入/删除联系人的更多信息,请查看我的第一个问题。

    【讨论】:

    • 感谢您的代码。您的图像代码几乎可以工作。但问题是在编辑图像后,它只在详细视图图片(本地联系人)中更新图像,而不是在列表视图图片(本地联系人)中
    • 谢谢。花了一整天后,您的代码救了我。 (Y)
    • 就我而言,此解决方案不起作用,我不得不将 ContactsContract.Data.CONTACT_ID 更改为 ContactsContract.Data.RAW_CONTACT_ID 并提供 raw_id
    【解决方案2】:

    我不确定这是否对你有帮助,但是我找到了一篇关于contact_id 和 raw_contact_id 之间区别的博客:

    http://android-contact-id-vs-raw-contact-id.blogspot.de/

    在此博客中,他很好地解释了联系人 api 的工作原理,如果我理解正确,您必须使用 raw_contact_id 更改您的条目。所以忘记更新的contact_id并更改您的更新,以便更改raw_contact_id条目。我大致猜测它看起来像这样:

    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
    .withSelection(RawContacts._ID + "=?", new String[]{entertheraw_contact_id})
    .withValue(StructuredName.DISPLAY_NAME, "Lost Symbol Characters")
    .build());
    getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    

    我希望这对您有所帮助,并再次感谢您之前的帮助表格。

    【讨论】:

    • 好吧,我尝试使用您的源代码,但它不起作用。我已经切换回我以前的代码,它给了我 RAW_CONTACT_ID。然后我用你的修改了我的 SC。但是什么也没发生……
    • 我唯一想到的可能是使用 ops.add(ContentProviderOperation.newUpdate(RawContacts.CONTENT_URI) 而不是 ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)。这可以解决问题
    • 下面的代码更新了联系人的姓名以及他的电话号码:s Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI); builder.withSelection(ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + "=?", new String[]{String.valueOf(r.getBook_id())}); builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, r.getFirstName().replace(" ", "-")+ " " +r.getLastName().replace(" ", "-")); ops.add(builder.build());
    • 感谢您发布正确答案。当您使用 rawContact 更新时,原始的 contact_id 会改变还是保持不变?您可以使用以前没有的信息更新 rawContact 吗?我的意思是你能用一张图片更新 rawContact,即使它确实有一个插入吗?
    • 没问题。是的 raw_contact_id 和 contact_id 保持不变。当您将 id 存储到数据库中时,这会容易得多。是的,您可以更新以前未填写的字段。
    【解决方案3】:

    要更新联系人,您需要同时拥有 contactIdRawContact id...所以在更新时将此也添加为 where 子句/选择参数中的值..

    类似的东西..

    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
    
            //------------------------------------------------------ Names
    
            ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                    .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
                    .withValue(ContactsContract.Data.MIMETYPE,
                            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                            .withValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX, data.getTitle())
                            .withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, data.getSuffix())
                            .withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, data.getFirstName())
                            .withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, data.getMiddleName())
                            .withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, data.getSuffix())
                            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, data.getFirstName()+" "+data.getMiddleName()).build());
    

    【讨论】:

    • 对不起,我不明白。我应该在何时何地使用该代码?我的电话簿由以前的联系人条目(用户在安装应用程序之前所做的)和应用程序创建的条目组成。我将使用整个源代码编辑我的第一篇文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2014-12-28
    • 1970-01-01
    相关资源
    最近更新 更多