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

问题描述 投票:0回答:1

我在需要更新本地电话簿联系人中的多个移动电话号码,座机号码和电子邮件,网站,地址时遇到问题。

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

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

我也只引用了很少的链接,但这也没有帮助。

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个回答
0
投票
  1. 一个可能是参数名称错误或实际错误的问题是您的选择是请求一个RAW_CONTACT_ID并提供一个称为contactId的参数,我不确定contactId中存储了什么,但是rawContactIdcontactId之间有很大的区别,因此,如果确实是contactId,则您的操作将找不到任何要更新的内容(或更糟糕的是,更新了错误的联系人)。
  2. 第二个问题是,您的两个循环(在userInfoMobileNosuserInfoGmails上)始终更新(覆盖)相同的数据行,因此最终您应该仅以联系方式中的最后一个值结束。您也不会检查联系人详细信息中是否有适合您选择的数据行,如果没有,则没有行可更新,因此代码将无济于事。
  3. 第三问题,但这可能是有意的,不确定您希望应用程序如何工作,是假设您使用了信息项类型,即,您仅在电话为TYPE_MOBILE的情况下更新电话,而仅在电话为TYPE_WORK的情况下更新电子邮件,如果该联系人还存储了其他电话和电子邮件怎么办?您的代码只会使那些内容保持不变,不确定是否是故意的。

要解决问题一,只需确保contactId中的值是Raw ContactId并更改参数名称。对于第二个问题,您应该改为删除并插入,请参见下面的代码。对于第三个问题,您需要更改选择代码(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));
© www.soinside.com 2019 - 2024. All rights reserved.