为什么contentResolver.query()从联系人中返回重复项?
因此,我使用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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我们回顾一下Contactscontract DB的组织方式:
还有伪表,例如
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:
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 examplePhone.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 namedAmber Altingle
.This is not duplication in the query code, but possibly duplication in the contact creation code.