如何使用ContentProviderOperation将城市字段添加到Android中的联系人

我正在创建一个联系人应用程序,它将具有联系人应用程序的所有基本功能(当然还有一些其他功能)。在实现基本功能时,我被困在一个地方:

我正在进行一项活动,用户可以在其中更改联系人的城市名称。如果用户已经有一个城市,则可以使用以下代码进行更新:

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String contactId = id; // got it from ContactsContract.Contacts._ID
String mimeType = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE;
String selection = ContactsContract.Data.CONTact_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredPostal.TYPE + " = ?";
String[] values = new String[]{contactId,mimeType,String.valueOf(ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME)};
ops.add(
 android.content.ContentProviderOperation.newUpdate(
  android.provider.ContactsContract.Data.CONTENT_URI)
   .withSelection(selection,values)
   .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY,"California")
   .build()
);
contentResolver.applyBatch(ContactsContract.AUTHORITY,ops);

但是,以上代码不适用于除了电话号码以外没有其他详细信息的联系人。浏览了很多之后,我发现可以通过以下方式进行操作:

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String rawContactId = id;
String mimeType = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE;
String[] values = new String[]{contactId,String.valueOf(ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME)};
ops.add(
 android.content.ContentProviderOperation.newInsert(
  android.provider.ContactsContract.Data.CONTENT_URI)
   .withValueBackReference(ContactsContract.Data.RAW_CONTact_ID,rawContactId)
   .withValue(ContactsContract.Data.MIMETYPE,mimeType)
   .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY,ops);

在上述情况下,我从rawContactId获得了ContactsContract.RawContacts.CONTENT_URI的{​​{1}}与正常的contactId相等。我为不同的帐户(Google,WhatsApp,Skype等)获得了不同的rawContactId。我尝试使用所有rawContactIds进行更新,但仍未更新。有人可以帮我解决该问题吗?

hewei600 回答:如何使用ContentProviderOperation将城市字段添加到Android中的联系人

在应用上述代码时,您没有指定完全不起作用的内容,但是我可以看到其中的一些问题。

首先,您需要对联系人数据在数​​据库中的存储方式有一个清晰的了解:

  1. Contacts-每个条目代表一个联系人,并将一个或多个RawContacts
  2. 组合在一起
  3. RawContacts-每个条目代表由某个SyncAdapter(例如Whatsapp,Google,Facebook,Viber)同步的联系人的数据,这些数据将多个Data条目分组
  4. Data-有关联系人,电子邮件,电话等的实际数据。每行是属于单个RawContact
  5. 的单个数据

问题1

因此,如果您要尝试更新现有的邮政地址,则应注意不要使用contactId作为密钥,因为单个联系人(由contactId引用)可能会有多个邮政地址-多个原始联系人中的-地址,每个原始联系人都具有多个邮政地址数据行。 您的newUpdate通话可能会更新所有地址中的城市。

因此,如果您有一个具有地址的联系人“ David”:

  • 美国纽约123巷
  • 456驱动器,美国密苏里州
  • 789胡同,法国巴黎

并且您的用户现在尝试将“巴黎”更新为“里昂”,您的代码可能会将所有3个地址更新为里昂。

然后,您的密钥必须是您要更新的特定Data._ID行的当前Data

问题2

如果您要向现有原始联系人中插入新数据行,例如全新的邮政地址,则需要指定您要插入的特定RawContact ID,而不使用withValueBackReference-仅在您现在创建一个全新的RawContact且不知道它将得到的RawContact ID时,此功能才有用但是,您正在反向引用新的RawContact将从先前对RawContact行的newInsert的调用获得的ID。

此外,在这种情况下,仅CITY值是不够的,因为您将获得仅包含CITY的整个邮政地址,如下所示:

  • 美国纽约123巷
  • 456驱动器,美国密苏里州
  • 789胡同,法国巴黎
  • 里昂

您要在此处执行的操作是收集所有邮政地址值,并将它们全部添加到一个新的 Data 行中,如下所示:

ops.add(
 ContentProviderOperation.newInsert(Data.CONTENT_URI)
   .withValue(Data.RAW_CONTACT_ID,rawContactId)
   .withValue(Data.MIMETYPE,mimeType)
   .withValue(StructuredPostal.STREET,"123 Lane")
   .withValue(StructuredPostal.CITY,"Los Angles")
   .withValue(StructuredPostal.REGION,"California")
   .withValue(StructuredPostal.COUNTRY,"United States")
   .build()
);

问题3

如果您尝试仅将 CITY 值插入现有邮寄地址行,则需要在其中进行更新而不是插入特定的数据ID,如下所示:

String selection = Data._ID + " = ?";
ops.add(
 ContentProviderOperation.newUpdate(Data.CONTENT_URI)
   .withSelection(selection,new String[]{ dataId })
   .withValue(StructuredPostal.CITY,"Los Angeles")
   .build()
);
本文链接:https://www.f2er.com/2664849.html

大家都在问