如何使用 CommonDataKinds.Phone 内部查询使此 ContactsContract.Contact 查询更快?
Posted
技术标签:
【中文标题】如何使用 CommonDataKinds.Phone 内部查询使此 ContactsContract.Contact 查询更快?【英文标题】:How can I make this ContactsContract.Contact query faster with CommonDataKinds.Phone inner query? 【发布时间】:2017-01-20 17:36:11 【问题描述】:我正在遍历Contacts
表,每次迭代都在Phone
表上进行迭代,所以它需要appx。 4 秒完成 243 个联系人的联系人列表(无需迭代它立即加载的电话号码)。我确信有办法让它更快。
已经做出预测以仅获取所需的列,但没有太大改进。也许我应该改进 SQLite 查询或以其他方式迭代:
Contact realmContact = new Contact();
Uri uri = Contacts.CONTENT_URI;
String[] projection =
Contacts.LOOKUP_KEY,
Contacts.DISPLAY_NAME_PRIMARY,
Contacts.LAST_TIME_CONTACTED,
Contacts.HAS_PHONE_NUMBER
;
String selection = "((" + CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " != '' ))";
Cursor phones = getActivity()
.getContentResolver()
.query(uri, projection, selection, null, null);
while (phones.moveToNext())
String id = phones.getString(phones.getColumnIndex(Contacts.LOOKUP_KEY));
String name = phones.getString(phones.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY));
String lastTimeContacted = phones.getString(phones.getColumnIndex(Contacts.LAST_TIME_CONTACTED));
long data = Long.parseLong(lastTimeContacted);
String date = new SimpleDateFormat("dd/MM/yyyy | HH:mm").format(new Date(data));
if (Integer.parseInt(phones.getString(phones.getColumnIndex(Contacts.HAS_PHONE_NUMBER))) > 0)
Cursor pCur = getActivity().getContentResolver().query(
CommonDataKinds.Phone.CONTENT_URI,
new String[]CommonDataKinds.Phone.NUMBER,
CommonDataKinds.Phone.LOOKUP_KEY + " = ?",
new String[]id, null);
int iterationCounter = 0;
String phoneNumber = "";
while (pCur.moveToNext())
phoneNumber += iterationCounter == 0 ?
pCur.getString(pCur.getColumnIndex(CommonDataKinds.Phone.NUMBER))
: "," + pCur.getString(pCur.getColumnIndex(CommonDataKinds.Phone.NUMBER));
iterationCounter += 1;
realmContact.setNumber(phoneNumber);
Log.i("asd-number", phoneNumber);
pCur.close();
realmContact.setId(id);
realmContact.setName(name);
realmContact.setLastTimeContacted(
getActivity().getResources()
.getString(R.string.contacts_list_fragment_last_call)
+ date);
realmContact.setIsBeingSaved(true);
_realm.insertOrUpdate(realmContact);
【问题讨论】:
只需在光标上迭代CommonDataKinds.Phone.CONTENT_URI
他们没有display_name
列
是的,他们有:ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
@pskink 如果联系人有多个号码,我会在列表中获得该数量的联系人重复项。有什么方法可以一口搞定一个联系人的所有号码?
【参考方案1】:
正如 @pskink 在 cmets 中提到的,您需要查询 Phone
表。
要按联系人获取电话列表,您可以维护一个从contactId
到List
的电话的HashMap
。
这里有一个小 sn-p 可能会有所帮助(您可能需要稍微调整一下集合,以便每个联系人只存储一次显示名称):
HashMap<Long, ArrayList<String>> phones = new HashMap<Long, ArrayList<String>>();
String[] projection = new String[] Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER ;
Cursor c = cr.query(Phone.CONTENT_URI, projection, null, null, null);
while (c != null && c.moveToNext())
long contactId = c.getLong(0);
ArrayList<String> list = phones.get(contactId);
if (list == null)
ArrayList<String> list = new ArrayList<String>();
phones.put(contactId, list);
list.add(c.getString(1) + " " + c.getString(2));
【讨论】:
以上是关于如何使用 CommonDataKinds.Phone 内部查询使此 ContactsContract.Contact 查询更快?的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?