Android 无法在本地电话簿中以编程方式更新联系人详细信息

Android Not able to update contact details programatically in local phonebook

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

如果联系人已存在于 phone 书中,那么我正在尝试更新其详细信息。

下面是我正在尝试的代码。它正在无误地执行,但没有多个移动电话、固定电话、电子邮件等未反映在 phone-该联系人的预订中,因为多个数据是他们的。

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

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

如有任何帮助,我们将不胜感激。我试过调试但找不到问题。

  1. 一个可能是参数名称错误或实际错误的问题是您的选择请求 RAW_CONTACT_ID 并提供名为 contactId 的参数,我不确定是什么存储在 contactId 中,但 rawContactIdcontactId 之间存在很大差异,因此如果这确实是一个 contactId,您的操作将找不到任何要更新的内容(甚至更糟,更新错误的联系人).
  2. 第二个问题是你的两个循环(在 userInfoMobileNosuserInfoGmails 上)不断更新(覆盖)同一个数据行,所以最终你应该只得到联系方式。 您也没有检查联系人详细信息中是否有适合您选择的数据行,如果没有,则没有要更新的行,因此代码将什么都不做。
  3. 第三个问题,但它可能是故意的,不确定您希望您的应用程序如何工作,是您假定信息项类型,即您只更新 phone 如果它是 TYPE_MOBILE ,并且您只更新 TYPE_WORK 的电子邮件,如果为该联系人存储了其他 phone 和电子邮件怎么办?您的代码将简单地保持那些不变,不确定是否有意。

要解决第一个问题,只需确保 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));