了解安卓联系人的架构

2022-09-02 21:28:48

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

所以我读了几篇帖子。我知道,每当联系人发生更改时,我们都可以通过内容观察器获得通知,但是我们无法获得已添加/更新/删除的联系人。因此,我已经阅读了官方API,并准备了我的设计如何捕获该特定联系人。

所以我一开始的想法

  1. 我们将存储所有联系人ID,已删除的标志和版本
  2. 每当联系人更改时,我都会从Android系统获得表的行数和行数。
  3. 如果我的行计数小于系统行计数,则联系人已被删除。
  4. 如果我的行计数大于系统行计数,则表示已添加联系人。
  5. 如果这些不是这种情况,那么其中一个联系人版本已更改。

我还了解到,如果联系人被用户删除,Android不会删除它,但它在已删除的标志上设置了0。因此,在这些情况下,行计数将相同。

Android 还会多次更改联系人的行 ID,如官方文档中所述。那么我们如何像查找uri一样唯一地识别它们,如果不是,那么我们也必须为此放置观察者。

所以我想知道以上是否正确?在添加联系人的情况下,是否会将其添加到光标的最后一行,或者不意味着如果我检查系统数据库的最后一行以获取联系人,它将为我添加或不添加联系人。


答案 1

让我尽可能多地解释。基本上,您的策略看起来相当不错,但实际上它比您想象的要复杂一些。

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

这也是为什么很难唯一地识别联系人的原因,因为您可以随时拆分或加入他们。 对于这种情况来说不是很方便。LOOKUP_KEY

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

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


答案 2

我认为最佳做法是监视联系人何时聚合到另一个联系人,并通过联系人名称(而不是_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。如果您需要通过某些数据元素(如电子邮件地址,昵称等)查找联系人,请使用针对ContractsContract.Data表的查询。结果将包含联系人ID,姓名等。


但是,问题是,您的联系人列表中可能有两个不是同一个人的“菲利普莫里斯”。

有关更多信息,请参阅 Android 类文档的此部分


推荐