了解Android联系人的架构

时间:2013-04-04 13:39:49

标签: java android android-contacts

我正在开发一款Android应用,需要知道何时添加/更新/删除联系人。

所以我读了几篇帖子。我知道,只要联系人发生变更,我们就可以通过内容观察员获得通知,但我们无法获得添加/更新/删除的联系人。所以我已阅读官方API并准备我的设计如何捕获该特定联系人。

所以我在开始时的想法

  1. 我们将存储所有联系人ID,已删除标志和版本
  2. 每当联系人发生变化时,我都会从Android的系统中获取表格的行数和行数。
  3. 如果我的rowcount小于系统行数,则联系人已被删除。
  4. 如果我的行数大于系统行数,则添加了联系人。
  5. 如果不是这些情况,则其中一个联系人版本已更改。
  6. 我还了解到,如果用户删除了联系人,Android不会删除该联系人,但在删除的标志上设置为0。所以在这些情况下,行数将是相同的。

    Android也会按照官方文档中的说明多次更改联系人的行ID。那么我们如何能够像查询uri一样唯一地识别它们,如果没有,那么我们也必须为它设置观察者。

    所以我想知道上述内容是否正确?在添加联系人的情况下,它会被添加到游标的最后一行或者不是意味着如果我检查系统数据库的最后一行是否有联系,它会给我添加的联系人。

2 个答案:

答案 0 :(得分:13)

让我尽可能多地解释一下。基本上你的政策看起来很不错,但实际上它比你想象的要复杂一点。

在Android上,联系人可以与多个raw contacts相关联,这些ContactContracts.RawContacts可能来自许多数据提供商,例如Google,Facebook,Skype等。例如,如果您本地联系人中的某个朋友也在使用Skype,则ContactsContract.Contacts中会分别存在两个原始联系人,但是当您查询{{{}}时,它们会自动聚合并显示为一个联系人3}}。

这也是为什么很难单独识别联系人,因为you can split or join them随时都可以。 LOOKUP_KEY对于这种情况不是很方便。

除Google之外的许多应用仅提供单向同步,仅从服务到联系人,因此它们是只读的。在这种情况下,删除的标志将不会被使用,只是在同步过程中被删除。因此,你不能简单地依靠旗帜。

虽然没有一个好的简单解决方案,但我想如果您观察到特定的RawContacts而不是Contacts,那么实现您想要的更容易。希望这有助于您理解。

答案 1 :(得分:8)

我认为最佳做法是监控联系人何时聚合到另一个联系人并通过contactName识别它们,而不是_ID或CONTACT_ID。 看看这个可能的联系人操作:

插入

无法明确创建联系人。插入原始联系人后,提供者将首先尝试查找代表同一个人的联系人。如果找到一个,则原始联系人的CONTACT_ID列将获取聚合联系人的_ID。如果未找到匹配项,提供程序将自动插入新的联系人并将其_ID放入新插入的原始联系人的CONTACT_ID列中。

<强>更新

只有某些联系人列可以修改:TIMES_CONTACTED,LAST_TIME_CONTACTED,STARRED,CUSTOM_RINGTONE,SEND_TO_VOICEMAIL。更改联系人上的任何这些列也会在所有组成原始联系人上更改它们。

删除

小心删除联系人!删除聚合联系人将删除所有组成原始联系人。相应的同步适配器将注意到其各自原始联系人的删除,并将其从后端存储中删除。

<强>查询

如果您需要阅读单个联系人,请考虑使用CONTENT_LOOKUP_URI而不是CONTENT_URI。 如果您需要通过电话号码查找联系人,请使用针对此目的进行优化的PhoneLookup.CONTENT_FILTER_URI。 如果您需要按部分名称查找联系人,例如要生成按类型过滤的建议,请使用CONTENT_FILTER_URI URI。 如果您需要通过电子邮件地址,昵称等某些数据元素查找联系人,请对ContactsContract.Data表使用查询。结果将包含联系人ID,姓名等。


但问题是,您的联系人列表中可能有两个“Phillip Morris”并非同一个人。

有关详细信息,请参阅Android {C ++文档的this section