【问题标题】:Android Not able to update contact details programatically in local phonebookAndroid 无法在本地电话簿中以编程方式更新联系人详细信息
【发布时间】:2020-08-24 04:10:51
【问题描述】:

我遇到了需要更新多个手机号码、固定电话号码和电子邮件、网站、本地电话簿联系人中的地址的问题。

如果电话簿中已经存在联系人,那么我正在尝试更新其详细信息。

下面是我正在尝试的代码。它正在执行而没有错误,但没有多个手机号码、固定电话、电子邮件等没有反映在该联系人的电话簿中,因为多个数据是他们的。

我还提到了一些链接,但这也没有帮助。

String whereMobile = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
            ContactsContract.Data.MIMETYPE + " = ? AND " +
            ContactsContract.CommonDataKinds.Phone.TYPE + " = ? ";

    String[] paramsMobile = new String[]{String.valueOf(contactID),
            ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
            String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)};


    if (userInfoMobileNos != null && !userInfoMobileNos.isEmpty()) {
        for (int iUserMobile = 0; iUserMobile < userInfoMobileNos.size(); iUserMobile++) {

            operationList.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
                    .withSelection(whereMobile, paramsMobile)
                    .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, userInfoMobileNos.get(iUserMobile).getPhoneNumber())
                    .build());
        }

    }


String whereGmail = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
                ContactsContract.Data.MIMETYPE + " = ? AND " +
                ContactsContract.CommonDataKinds.Email.TYPE + " = ? ";

    String[] paramsGmail = new String[]{String.valueOf(contactID),
    ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
    String.valueOf(ContactsContract.CommonDataKinds.Email.TYPE_WORK)};

    if (userInfoGmails != null && !userInfoGmails.isEmpty()) {
    for (int iUserGmail = 0; iUserGmail < userInfoGmails.size(); iUserGmail++) {

      operationList.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
                        .withSelection(whereGmail, paramsGmail)
                        .withValue(ContactsContract.CommonDataKinds.Email.DATA, userInfoGmails.get(iUserGmail).getEmail())
                        .build());
    }

}

更新代码

private void updateNew(Context context, int rawContactID) {
        ArrayList<ContentProviderOperation> operationList = new ArrayList<>();

        String whereMobile = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
                ContactsContract.Data.MIMETYPE + " = ? AND " +
                ContactsContract.CommonDataKinds.Phone.TYPE + " = ? ";

        String[] paramsMobile = new String[]{String.valueOf(rawContactID),
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
                String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)};

// First delete all the existing phones with type mobile, if any exist
        operationList.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
                .withSelection(whereMobile, paramsMobile)
                .build());

// Next, insert all the updated phones:
        for (MobileNumbersItem infoMobileNo : userInfoMobileNos) { // <== change the class to the one you're using in userInfoMobileNos
            operationList.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) // <== insert not update!
                    .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
                    .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                    .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                    .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, infoMobileNo.getPhoneNumber())
                    .build());
        }

        String whereGmail = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
                ContactsContract.Data.MIMETYPE + " = ? AND " +
                ContactsContract.CommonDataKinds.Email.TYPE + " = ? ";

        String[] paramsGmail = new String[]{String.valueOf(rawContactID),
                ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
                String.valueOf(ContactsContract.CommonDataKinds.Email.TYPE_WORK)};

        // First delete all the existing emails with type work, if any exist
        operationList.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
                .withSelection(whereGmail, paramsGmail)
                .build());

        // Next, insert all the updated emails:
        for (GmailsItem userInfoGmail : userInfoGmails) { // <== change the class here too
            operationList.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                    .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
                    .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                    .withValue(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK)
                    .withValue(ContactsContract.CommonDataKinds.Email.DATA, userInfoGmail.getEmail())
                    .build());
        }


        try {
            // don't forget to apply the operations now:
            ContentProviderResult[] results = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operationList);
            Log.d("UPDATE CONTACRT", "results=" + Arrays.toString(results));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Log.e("updateContactError", Objects.requireNonNull(e.getMessage()));
        }
    }

我们将不胜感激。我已经尝试调试但无法找到问题。

【问题讨论】:

    标签: android contacts android-contacts insert-update


    【解决方案1】:
    1. 一个可能是错误的参数名称或实际错误的问题是您的选择请求RAW_CONTACT_ID 并提供一个名为contactId 的参数,我不确定contactId 中存储的内容,但是rawContactId 和 contactId 之间存在很大差异,因此如果这确实是一个 contactId,您的操作将找不到任何要更新的内容(或者更糟糕的是,更新错误的联系人)。
    2. 第二个问题是您的两个循环(通过userInfoMobileNos 和userInfoGmails)不断更新(覆盖)相同的数据行,因此最终您应该只得到联系方式中的最后一个值。 您也没有检查联系人详细信息中是否有适合您选择的数据行,如果没有,将没有要更新的行,因此代码将什么也不做。
    3. 第三个问题,但它可能是故意的,不确定您希望您的应用程序如何工作,是您假设信息项类型,即您只更新手机,如果它是 TYPE_MOBILE,您只更新电子邮件,如果它是 TYPE_WORK ,如果为该联系人存储了其他电话和电子邮件怎么办?您的代码只会保持这些不变,不确定是否有意。

    要解决问题一,只需确保 contactId 中的值是 RawContactId 并更改参数的名称。 对于第二个问题,您应该改为执行删除和插入操作,请参见下面的代码。 对于第三个问题,您需要更改选择代码 (paramsMobile) 以删除它的标签假设。

    这是建议的代码:

    String whereMobile = Data.RAW_CONTACT_ID + " = ? AND " +
            Data.MIMETYPE + " = ? AND " +
            Phone.TYPE + " = ? ";
    
    String[] paramsMobile = new String[]{String.valueOf(rawContactID),
            Phone.CONTENT_ITEM_TYPE,
            String.valueOf(Phone.TYPE_MOBILE)};
    
    // First delete all the existing phones with type mobile, if any exist
    operationList.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)
        .withSelection(whereMobile, paramsMobile)
        .build());
    
    // Next, insert all the updated phones:
    for (UserInfo infoMobileNo : userInfoMobileNos) { // <== change the class to the one you're using in userInfoMobileNos
        operationList.add(ContentProviderOperation.newInsert(Data.CONTENT_URI) // <== insert not update!
            operationList.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) // <== insert not update!
                    .withValue(Data.RAW_CONTACT_ID, rawContactID)
                    .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
                    .withValue(Phone.TYPE, Phone.TYPE_MOBILE)
                    .withValue(Phone.NUMBER, infoMobileNo.getPhoneNumber())
                    .build());
    }
    
    String whereGmail = Data.RAW_CONTACT_ID + " = ? AND " +
                Data.MIMETYPE + " = ? AND " +
                Email.TYPE + " = ? ";
    
    String[] paramsGmail = new String[]{String.valueOf(rawContactID),
    Email.CONTENT_ITEM_TYPE,
    String.valueOf(Email.TYPE_WORK)};
    
    // First delete all the existing emails with type work, if any exist
    operationList.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)
        .withSelection(whereGmail, paramsGmail)
        .build());
    
    // Next, insert all the updated emails:
    for (UserInfo userInfoGmail : userInfoGmails) { // <== change the class here too
        operationList.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
            .withValue(Data.RAW_CONTACT_ID, rawContactID)
                    .withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
                    .withValue(Email.TYPE, Email.TYPE_WORK)
                    .withValue(Email.DATA, userInfoGmail.getEmail())
                    .build());
    }
    
    // don't forget to apply the operations now:
    ContentProviderResult[] results = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operationList);
    Log.d("UPDATE CONTACRT", "results=" + Arrays.toString(results));
    

    【讨论】:

    • 感谢您的回复,我们将对此进行调查并回复您。contactId id 实际上是一个原始联系人 id,我正在按名称获取它...
    • 使用此代码时,它在 withSelection 上崩溃,因为它只允许在更新、删除时,所以在插入时我尝试使用用户代码并解决了错误,但仍然更新联系人结果 = [] 空白。这是代码,你可以看看。我已经用你更新的代码更新了问题。 @marmor
    • newInsert 很好,我没有测试我的代码...我已经更新了答案中的代码。有一条评论,这里不需要withValueBackReference,这只是在你添加一个新的 RawContact 的情况下,你不是。
    • 除了上述注释之外,如果您尝试编辑的原始联系人是只读联系人,此代码有时可能不起作用。如果您在 Google 原始联系人上运行此程序(使用上面的 withValue 修复而不是 withValueBackReference,它是否有效?
    • 不要完全删除它,只需将其更改为常规 withValue 看我更新的代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    相关资源
    最近更新 更多