为什么contentResolver.query()从联系人中返回重复项?

发布于 2025-02-01 12:50:17 字数 3657 浏览 4 评论 0原文

因此,我使用Android的本机实现在这些联系人中阅读,其中使用约1,056个联系人的测试电话。我遇到的问题是它相当慢,所以我正在记录Cursor.movetonext()的结果,并且看到它正在以重叠的,重复的方式读取最后一个联系人。但是,它确实已经实现了以前的逻辑,因此该应用程序将此条目列表的哈希版本与先前保存的一个列表进行比较,这最终将条目带回了正确的值,顺序和内容。但是,使用下面的代码,在最坏的情况下,它将再次将整个联系人列表删除,然后将其放在同一列表中(本质上是两次读取相同的地址簿并将其读入,并将其翻倍)。您的联系人列表的越糟糕(像我有9个联系人的那个银河系一样,较小的书籍似乎都不会受到影响;而我的手机约为106,而这款测试仪的测试仪具有1,053的意义),则较大手机在完全更新,准确和完成之前,我已经测试了一分钟半到两分钟以上的时间。

令人困惑的是,即使在所有这些重复之后,支票都设法返回并确切地为 它应该是什么(即1,053个联系电话,我看到它添加了第2106行,然后是它立即加载适当的1,053个联系簿)。

这是我的光标的定义方式:

Cursor c = mContext.getContentResolver().query(addressBookURI, 
CONTACTS_QUERY_PROJECTION, CONTACTS_QUERY_SELECTION, null, CONTACTS_QUERY_SORT);

这是所述光标“ c”的每个组件:

    private static final Uri addressBookURI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "1").build();

    private static final String[] CONTACTS_QUERY_PROJECTION = {
        ContactsContract.Data.CONTACT_ID,
        ContactsContract.Contacts.HAS_PHONE_NUMBER,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Data.DATA1,
        ContactsContract.Data.DATA2,
        "account_name"
    };
    
    private static final String CONTACTS_QUERY_SELECTION = "in_default_directory=1 and has_phone_number=1 and mimetype='vnd.android.cursor.item/phone_v2'";
    private static final String CONTACTS_QUERY_SORT = "contact_id ASC";

处理光标“ c”的读取:

            List<String[]> entries = new ArrayList<>();
            while (c.moveToNext()) {
            String id = c.getString(0);
            String name = c.getString(2);
            String phone = c.getString(3);
            String type = c.getString(4);
            String account_name = c.getString(5);
            Log.d(sTag, "contact:row:" + id + ":" + name + ":" + phone + ":" + type + ":" + 
            account_name);
            
            entries.add(new String[]{id, name, phone, type});

是在log.d.d()语句中,我可以看到联系人的重复项,其中唯一的区别在原始触点和随访重复项之间是“ ID”变量(不断增加,周期)。

例如(如果发生较小的触点发生;所有值都组成):

联系人:行:1:毛琳lastPass:4145737719:3:D8:0B:0B:0B:9A:9A:CC:88:BF

接触:ROW:2:BLONDELL:BLONDELL:BLONDELL:BLONDELL Sosig:4013008122:3:D8:0B:9A:CC:88:BF

contact:row:3:Amber Altingle:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:4:Frank Helgenson: 8885554422:2:D8:0B:9A:

CC:88:BF联系:5:5:HIRO XIN:8888885554422:2:D8:0B:9A:9A:9A:CC:88:BF

接触2:D8:0B:9A:CC:88:BF

联系人:ROW:7:HENRY HALGOR:6316773675:2:D8:0B:0B:0B:9A:9A:CC:88:BF接触:8:Hammy Xevronic:Hammy Xevronic:6316743675:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2

:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2: D8:0B:9A:CC:88:BF

contact:row:9:Maurine Lastpass:4145737719:3:D8:0B:9A:CC:88:BF

contact:row:10:Blondell Sosig:4013008122:3:D8: 0B:9A:CC:88:BF

contact:row:11:Amber Altingle:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:12:Frank Helgenson:8885554422:2:D8:0B: 9A:CC:88:BF

contact:row:13:Hiro Xin:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:14:Baley Balix:6316773675:2:D8:0B:9A: CC:88:BF

contact:row:15:Henry Halgor:6316773675:2:D8:0B:9A:CC:88:BF

contact:row:16:Hammy Xevronic:6316773675:2:D8:0B:9A:CC: 88:BF

我尝试存储第一个联系人,并让其从光标读取直到与该联系人匹配,但是由于“ ID”变量不断增加,因此它使触点与众不同,以至于足够忽略。我删除了联系人的ID部分,将URI从默认值更改为emplacilit remove_duplicate_entries = 1参数的默认设备,我尝试使用contactscontract.data._count进行“真实”计数,以便检查数字编号光标上的条目针对它,但这只是用“没有这样的列_count”崩溃。

有什么原因是,光标会拉出这样的重复联系人?我的查询的结构有什么问题,导致这种重复?

So I'm reading in these contacts using Android's native implementation, using a test phone with about 1,056 contacts on it. The problem I'm having is that it's rather slow, so I'm logging the outcomes of my cursor.moveToNext(), and seeing that it's reading in contacts past the last in an overlapping, duplicating fashion. It does, however, have previous logic implemented so the app compares the hashed version of this list of entries to the previously saved one every second... which eventually brings the entries back to the correct value, order, and contents. However, using the code below, at worst it's pulling the entire contact list AGAIN, and then putting it in there with the same list (essentially reads the same address book twice and reads it in, doubling entries). This gets worse the larger your contact list is (smaller books, like this Galaxy I have with 9 contacts, don't seem to be affected; whereas my phone with about 106 is slightly, and this tester with 1,053 significantly) with the larger phones I've tested taking upwards of a minute and a half to two minutes before it's fully updated, accurate, and done.

What's confusing is that it somehow, even after all this duplication, the check manages to come back and be exactly what it was supposed to be (i.e 1,053 contact phone I see it adding the 2,106th row, then it immediately loads the proper 1,053 contact book).

Here's how my cursor is defined:

Cursor c = mContext.getContentResolver().query(addressBookURI, 
CONTACTS_QUERY_PROJECTION, CONTACTS_QUERY_SELECTION, null, CONTACTS_QUERY_SORT);

Here's each of the components of said Cursor "c":

    private static final Uri addressBookURI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "1").build();

    private static final String[] CONTACTS_QUERY_PROJECTION = {
        ContactsContract.Data.CONTACT_ID,
        ContactsContract.Contacts.HAS_PHONE_NUMBER,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Data.DATA1,
        ContactsContract.Data.DATA2,
        "account_name"
    };
    
    private static final String CONTACTS_QUERY_SELECTION = "in_default_directory=1 and has_phone_number=1 and mimetype='vnd.android.cursor.item/phone_v2'";
    private static final String CONTACTS_QUERY_SORT = "contact_id ASC";

Processing the Cursor "c"'s reads:

            List<String[]> entries = new ArrayList<>();
            while (c.moveToNext()) {
            String id = c.getString(0);
            String name = c.getString(2);
            String phone = c.getString(3);
            String type = c.getString(4);
            String account_name = c.getString(5);
            Log.d(sTag, "contact:row:" + id + ":" + name + ":" + phone + ":" + type + ":" + 
            account_name);
            
            entries.add(new String[]{id, name, phone, type});

It's in that Log.d() statement where I can see duplicates of contacts, wherein the only difference between the original contact and follow-up duplicates is the "id" variable (keeps increasing, period).

For example (if it happened with smaller amounts of contacts; all values are made up):

contact:row:1:Maurine Lastpass:4145737719:3:D8:0B:9A:CC:88:BF

contact:row:2:Blondell Sosig:4013008122:3:D8:0B:9A:CC:88:BF

contact:row:3:Amber Altingle:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:4:Frank Helgenson:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:5:Hiro Xin:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:6:Baley Balix:6316773675:2:D8:0B:9A:CC:88:BF

contact:row:7:Henry Halgor:6316773675:2:D8:0B:9A:CC:88:BF

contact:row:8:Hammy Xevronic:6316773675:2:D8:0B:9A:CC:88:BF

contact:row:9:Maurine Lastpass:4145737719:3:D8:0B:9A:CC:88:BF

contact:row:10:Blondell Sosig:4013008122:3:D8:0B:9A:CC:88:BF

contact:row:11:Amber Altingle:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:12:Frank Helgenson:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:13:Hiro Xin:8885554422:2:D8:0B:9A:CC:88:BF

contact:row:14:Baley Balix:6316773675:2:D8:0B:9A:CC:88:BF

contact:row:15:Henry Halgor:6316773675:2:D8:0B:9A:CC:88:BF

contact:row:16:Hammy Xevronic:6316773675:2:D8:0B:9A:CC:88:BF

I've tried storing the very first contact and letting it read from the Cursor until it matches up with that contact, but since the "id" variable keeps increasing, it makes the contact different enough to be ignored. I removed the ID portion of the contact, changed the URI from the default to one with an explicit REMOVE_DUPLICATE_ENTRIES = 1 parameter on it, and I tried to bring in the "real" count using ContactsContract.Data._COUNT in order to check the number of entries on the cursor against it, but that just crashes with "no such column _COUNT".

Is there any reason why the cursor would be pulling duplicate contacts like this? Is there something wrong with the structure of my query that is causing this sort of duplication?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泪是无色的血 2025-02-08 12:50:17

让我们回顾一下Contactscontract DB的组织方式:

  1. 联系人表 - 每个触点包含一行,但几乎没有任何信息
  2. RAWCONTACTS表 - 可以有多行,每行分配给一个单一的接触ID(从上一张表)包含一个逻辑组多个数据行通常适用于单个SyncProvider,例如Google。
  3. 数据表 - 包含RAWCONTACT的实际数据,每行都有一个模拟列列,该列指出了该行的哪种数据(电话,电子邮件,名称等) + 15个数据列以保存信息本身。

还有伪表,例如ContactsContract.CommonDatakinds.phone您在代码中查询的基本上是在数据表上查询的,但具有特定的模拟物值,例如phone.content_item_item_type

在您的代码中,您正在通过Commondatakinds.phone.content_uri查询,这意味着您要求DB中的所有不同电话号码。
因此,如果单个联系人有3个电话号码,则该联系人将获得3行(每个联系人的电话号码)。

无论您的输出如何,每个联系人似乎都有一个电话号码,但似乎可以复制联系人。
因此,例如Amber Altingle具有联系ID 3和11,这意味着您有两个单独的联系人Amber Altingle
这不是查询代码中的重复,而是联系人创建代码中的重复。

let's recap the way ContactsContract DB is organized:

  1. Contacts table - contains one row per contact, but hardly any information
  2. RawContacts table - can have multiple rows, each assigned to a single contact-ID (from the previous table), contains a logical group of multiple Data rows usually for a single SyncProvider such as Google.
  3. Data table - contains the actual data of a RawContact, each row has a MIMETYPE column which states what kind of data this row is about (phone, email, name, etc.) + 15 data columns to hold the information itself.

There are also pseudo tables, such as ContactsContract.CommonDataKinds.Phone which you are querying in your code, which basically queries over the Data table but with a specific MIMETYPE value, for example Phone.CONTENT_ITEM_TYPE.

In your code you are querying over CommonDataKinds.Phone.CONTENT_URI which means you are asking for all the different phone numbers in the DB.
So if a single contact has 3 phone numbers, you will get 3 rows for that contact (each with a different phone number).

However looking at your output, it seems like every contact has a single phone number in the DB, but it looks like the contacts themselves are duplicated.
So for example Amber Altingle has contact ID 3 and also 11, which means you have two separate contacts named Amber Altingle.
This is not duplication in the query code, but possibly duplication in the contact creation code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文