联系人与原始联系人之间有什么区别?

24

我有一个“dump”实用程序,我正在使用它来研究ContactsContract,因为我在文档中不能完全理解它。当我转储联系人时,它在表中计算263个记录,但是我的设备上的联系人应用程序列出我有244个(“显示244个联系人”)

有人能解释这个差异吗?

我的Sprint LG的联系人应用程序针对我同步的每个帐户都有显示选项,我已经检查了所有选项,因此不应该有任何过滤。

我在实用程序中使用的主要URI是:

    Uri uriRawContacts = ContactsContract.RawContacts.CONTENT_URI;
    String[] projection = new String [] {
            ContactsContract.RawContactsEntity._ID,
            ContactsContract.RawContactsEntity.CONTACT_ID,
            ContactsContract.RawContactsEntity.DELETED,
            ContactsContract.RawContactsEntity.AGGREGATION_MODE,
    };
    Cursor cursorRaw = cr.query(uriRawContacts, projection, null, null, null);
    DumpCursor.dumpAnyCursor(getApplicationContext(), "RawContacts", cr, cursorRaw, ",");

接下来执行以下操作(对于上面查询中的每个_ID):

                long rawContactId = Long.parseLong(anyCursor.getString(anyCursor.getColumnIndex(RawContacts.CONTACT_ID)));

                Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
                 Uri entityUri = Uri.withAppendedPath(rawContactUri, Entity.CONTENT_DIRECTORY);

                 Log.d(TAG, "rawContactUri: " + rawContactUri.toString());
                 Log.d(TAG, "entityUri: " + entityUri.toString());

                 Cursor c = cr.query(entityUri, new String[] { RawContacts.SOURCE_ID, Entity.DATA_ID, Entity.MIMETYPE, Entity.DATA1 }, null, null, null);
我首先循环遍历第一个查询,显示投影中的所有列,然后使用第一个查询循环中的_ID字段,发出第二个查询并转储其所有列。引用答案中的项目列表如下:Contacts数据库分为3个表:联系人(contacts)、原始联系人(raw contacts)和数据(data)。每个表都包含一个列(_ID),它是自动递增的主键。数据表包含所有联系人信息,例如电话号码、邮件地址等。原始联系人指向实际创建的联系人。因此,在添加联系人时我们使用原始联系人。用户无法在联系人表中添加任何数据。此表中的数据由于联系人聚合而在内部填充。你的逻辑之所以对某些联系人有效,是因为contacts和raw contacts的_ID保持不变,直到发生任何联系人聚合。假设您添加了两个名为abc的联系人,这里raw contacts的_ID会增加两次,而contacts的_ID只会增加一次,因为这两个联系人由于联系人聚合而合并。请参阅引用以获取更详细的解释。更具体地说,建议您阅读有关聚合规则的内容。 Ref: 点击此处以获取以下原始引用文本

上一个已批准的编辑是错误的。如果您阅读原始内容,您会看到缺失的标点符号以及对三个表的重点强调。然后他/她将其称为“数据表'contacts'包含所有...”您已经修改了原作者正确陈述的内容。 - mobibob
2个回答

25

由于聚合规则导致了RawContacts合并到Contacts中,所以才会出现这种差异。

当您将联系人添加到RawContacts时,列表显示的是Contacts。因此导致计数上存在差异。

请在此处找到有关ContactsRawContactsData的一些描述。尽管问题不同,但您可能可以看到ContactsRawContacts之间的区别。


1
非常好的回答,加一。我认为这些信息非常重要,所以我打算将那个回答中的六个要点引用并转述到这个问答中。 - mobibob

5
三个表通常被称为它们的合同类名称。这些类为表使用的内容URI、列名和列值定义了常量: ContactsContract.Contacts 表:基于原始联系人行的聚合,表示不同人员的行。 ContactsContract.RawContacts 表:包含特定于用户帐户和类型的人员数据摘要的行。 ContactsContract.Data 表:包含原始联系人的详细信息,例如电子邮件地址或电话号码。
更多信息请点击

假设我想获取应用程序用于打开聊天意图的ID,例如Viber,我该怎么做?例如,如果Viber有一个联系人X,则为其分配了一些ID Y,该ID用于使用以下内容打开与此联系人的聊天意图:intent = new Intent(Intent.ACTION_VIEW,Uri.parse(“content://com.android.contacts/data/”+id)); intent.setPackage(“com.viber.voip”); - android developer
我找不到所需的ID。你能帮忙吗?我在这里发布了一个帖子:https://dev59.com/fJXfa4cB1Zd3GeqPYwa3 - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接