3

我想从 android 设备中检索 >10000 个联系人。要获得这么多的联系,大约需要 8-10 分钟。有没有其他可能的方法来做到这一点。我已经实现了一个工作正常的方法,但是当涉及大量联系人时,它需要时间来获取联系人。

 ContentResolver cr = getActivity().getApplication().getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {
            String id = cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts.DISPLAY_NAME));
            if (Integer.parseInt(cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                Cursor pCur = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
                        new String[]{id}, null);
                while (pCur.moveToNext()) {
                    int phoneType = pCur.getInt(pCur.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.TYPE));
                    String phoneNumber = pCur.getString(pCur.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));

                    phoneNumber = phoneNumber.replace(" ","");
                    phoneNumber = phoneNumber.replace("-","");

                    boolean addNumber = stringCheck(phoneNumber,symbols);

                    if (!addNumber){

                        if (phoneNumber.length() == 10){
                            addContact(phoneNumber,phoneType,name);
                        }else if (phoneNumber.length() == 11){
                            phoneNumber = phoneNumber.substring(1);
                            addContact(phoneNumber,phoneType,name);

                        }else if (phoneNumber.length() == 12){
                            phoneNumber = phoneNumber.substring(2);
                            addContact(phoneNumber,phoneType,name);

                        }else if (phoneNumber.length() == 13){
                            phoneNumber = phoneNumber.substring(3);
                            addContact(phoneNumber,phoneType,name);
                        }

                    }

                }
                pCur.close();
            }
        }
    }
4

4 回答 4

0

将您的获取过程保持在doInBackground方法中AyncTask,然后显示它。并且只获取那些首先需要的信息,例如,联系人姓名和 ID。

请参阅此 ans 以获得更多说明: 获取大量联系人

于 2016-12-21T06:17:01.140 回答
0

如果1000 个联系人中有900个有电话号码,则您当前正在查询 DB 901次,您可以将其减少到只有两个查询

  1. 给我所有的联系方式
  2. 给我所有的电话号码

然后,您使用contact-id两者上的字段将手机与正确的联系人匹配。

此外,正如其他答案中所述,您确实应该添加projection所有查询以提高性能。

您可以进行的另一项改进是避免运行时cur.getColumnIndex()调用,如果您有投影,您应该已经知道索引 - 所以使用硬编码

Map<Long, List<String>> phones = new HashMap<>();
ContentResolver cr = getActivity().getApplication().getContentResolver();

// First build a mapping: contact-id > list of phones
Cursor cur = cr.query(Phone.CONTENT_URI, new String[] { Phone.CONTACT_ID, Phone.Number }, null, null, null);
while (cur != null && cur.moveToNext()) {
   long contactId = cur.getLong(0);
   String phone = cur.getString(1);
   List list;
   if (phones.contains(contactId)) {
      list = phones.get(contactId);
   } else {
      list = new ArrayList<String>();
      phones.put(contactId, list);
   }
   list.add(phone);
}
cur.close();

// Next query for all contacts, and use the phones mapping
cur = cr.query(Contacts.CONTENT_URI, new String[] { Contacts._ID, Contacts.DISPLAY_NAME }, null, null, null);
while (cur != null && cur.moveToNext()) {
   long id = cur.getLong(0);
   String name = cur.getString(1);
   List<String> contactPhones = phones.get(id);
   addContact(id, name, contactPhones);
}
于 2016-12-25T15:16:46.663 回答
0

为了获取大量联系人,您必须使用 REST API 以页面的形式获取联系人。例如联系人的页面大小为 100。

一种可能的方法:

如果您在列表视图中显示联系人,那么您可以在用户滚动列表时获取数据。为此,您必须设置列表的阈值位置,即 80,因此当用户在滚动时到达第 80 位时,您可以点击下一个页面的其余 API 以获取新联系人并将这些联系人添加到列表视图中。

从您的评论中,我可以看到您需要所有联系人才能继续前进。为此,您可以在启动应用程序时启动意图服务。该服务将获取所有联系人并存储它们。您可以根据需要使用它们

于 2016-12-21T06:25:03.233 回答
0

这里有一些加速优化

String[] select = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER};

Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, select, null, null, null);

String[] selectOnly = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.TYPE};

Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        selectOnly,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
                        new String[]{id}, null);

如果可能,请在服务器端检查您的号码和长度。在异步任务中执行此操作。

于 2016-12-21T07:07:05.063 回答