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()));
}
}
如有任何帮助,我们将不胜感激。我试过调试但找不到问题。
- 一个可能是参数名称错误或实际错误的问题是您的选择请求
RAW_CONTACT_ID
并提供名为 contactId
的参数,我不确定是什么存储在 contactId
中,但 rawContactId
和 contactId
之间存在很大差异,因此如果这确实是一个 contactId,您的操作将找不到任何要更新的内容(甚至更糟,更新错误的联系人).
- 第二个问题是你的两个循环(在
userInfoMobileNos
和 userInfoGmails
上)不断更新(覆盖)同一个数据行,所以最终你应该只得到联系方式。
您也没有检查联系人详细信息中是否有适合您选择的数据行,如果没有,则没有要更新的行,因此代码将什么都不做。
- 第三个问题,但它可能是故意的,不确定您希望您的应用程序如何工作,是您假定信息项类型,即您只更新 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));
我遇到问题,我需要更新多个手机号码、固定电话号码和电子邮件、网站、本地地址 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()));
}
}
如有任何帮助,我们将不胜感激。我试过调试但找不到问题。
- 一个可能是参数名称错误或实际错误的问题是您的选择请求
RAW_CONTACT_ID
并提供名为contactId
的参数,我不确定是什么存储在contactId
中,但rawContactId
和contactId
之间存在很大差异,因此如果这确实是一个 contactId,您的操作将找不到任何要更新的内容(甚至更糟,更新错误的联系人). - 第二个问题是你的两个循环(在
userInfoMobileNos
和userInfoGmails
上)不断更新(覆盖)同一个数据行,所以最终你应该只得到联系方式。 您也没有检查联系人详细信息中是否有适合您选择的数据行,如果没有,则没有要更新的行,因此代码将什么都不做。 - 第三个问题,但它可能是故意的,不确定您希望您的应用程序如何工作,是您假定信息项类型,即您只更新 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));