【问题标题】:Android sdk Update contact with contact providerAndroid sdk 使用联系人提供商更新联系人
【发布时间】:2017-07-06 19:37:06
【问题描述】:

我首先提出这样的要求:

Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

    String[] projection = new String[]{
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.PHOTO_ID,
            ContactsContract.Contacts.HAS_PHONE_NUMBER,
            ContactsContract.CommonDataKinds.Phone.NUMBER
    };

    Cursor cursor = resolver.query(uri, projection, null, null, null);

    ArrayList<Contact> contactList = new ArrayList<> ();

    if (cursor != null && cursor.moveToFirst ()) {
        do {
            Contact contact = new Contact();
            contact.Id = cursor.getLong (cursor.getColumnIndex (projection [0]));
            contact.DisplayName = cursor.getString (cursor.getColumnIndex (projection [1]));
            contact.PhotoId = cursor.getString (cursor.getColumnIndex (projection [2]));
            contact.PhoneNumber = cursor.getString (cursor.getColumnIndex (projection [4]));

            contactList.add (contact);
        } while (cursor.moveToNext());

        cursor.close();
    }

    return contactList;

然后我使用第一个请求返回的 ID 来更新联系人,如下所示:

ArrayList<ContentProviderOperation> ops = new ArrayList<>();

    // Name
    ops.add(ContentProviderOperation
            .newUpdate(ContactsContract.Data.CONTENT_URI)
            .withSelection(
                    ContactsContract.Contacts._ID
                            + "=? AND "
                            + ContactsContract.Data.MIMETYPE
                            + "=?",
                    new String[] {
                            String.valueOf(contact.Id),
                            ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE })
            .withValue(ContactsContract.Contacts.DISPLAY_NAME, contact.DisplayName)
            .build());

    try {
        resolver.applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (OperationApplicationException e) {
        e.printStackTrace();
    }

但不幸的是,更新部分不起作用。 知道如何将第一个请求的结果与更新请求一起使用吗?

【问题讨论】:

    标签: android android-contacts


    【解决方案1】:

    您不能通过更新Data 表来更新Contacts 表中的字段。 投影中来自 Contacts.X 的所有字段都是通过隐式连接添加的,但实际上属于不同的表。

    如果我理解正确,您正在尝试更新联系人的显示名称,操作方法如下(确保从 ContactsContract 导入所有类):

    ops.add(ContentProviderOperation
            .newUpdate(Data.CONTENT_URI)
            .withSelection(Data.CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", new String[] { String.valueOf(contact.Id), StructuredName.CONTENT_ITEM_TYPE })
            .withValue(StructuredName.DISPLAY_NAME, contact.DisplayName)
            .build());
    

    另外,仅供参考,您不需要在第一个查询中使用cursor.getColumnIndex,只需这样做:

    contact.Id = cursor.getLong(0);
    contact.DisplayName = cursor.getString(1);
    contact.PhotoId = cursor.getString(2);
    contact.PhoneNumber = cursor.getString(4);
    

    文档

    相关原始联系人中的一些列也可用 通过隐式连接。其他列被排除为 在这种情况下无趣。

    ...

    关联的聚合联系人表的 ID 列 ContactsContract.Contacts 可以通过隐式连接到 ContactsContract.RawContacts 表,见上文。其余列 从这个表中也可以通过隐式连接获得。这个 便于通过单个数据元素的值进行查找,例如 电子邮件地址。

    【讨论】:

    • 太好了,谢谢!我会尽快尝试并告诉你它是否有效。所以我只需将 Contacts.CONTENT_URI 指定为 URI 而不是 Data.CONTENT_URI ?我这样做是因为我认为 display_name 存储在数据中。意思是更新查询会自己找到对应的数据表?
    • DISPLAY_NAME 不存储在Data 中,仅存储在Contacts 中,因此您只需修改Contacts 表即可。当您从Data 表中查询时(就像在您的第一个查询中一样),提供者将知道从Contacts 表中获取DISPLAY_NAME
    • 好的,我明白了,谢谢。在哪里可以找到有关 DISPLAY_NAME 的信息?我阅读了文档,上面写着“显示名称、电话号码、电子邮件、邮政地址、照片和网站详细信息行都在 ContactsContract.Data 表中找到。” (developer.android.com/guide/topics/providers/…) 这就是为什么它让我感到困惑。
    • 查看我的编辑。基本上你是对的,显示名称实际上保存在 Data 表中它自己的 mimetype (CommonDataKinds.StructuredName) 中,但你不必担心,因为它也存储在 Contacts 表中可用于查询的地方,例如您的
    • 好的,我试过了,但没用。它什么也不做。没有错误也没有更新。有什么想法吗?
    猜你喜欢
    • 2013-01-14
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多