从Android设备获取超过10000个联系人

时间:2016-12-21 05:52:41

标签: android device android-contacts contact import-contacts

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

let url = URL(string: "assets-library://asset/asset.JPG?id=1000000007&ext=JPG")
let asset = PHAsset.fetchAssets(withALAssetURLs: [url], options: nil)
guard let result = asset.firstObject else {
  return nil
}
let imageManager = PHImageManager.default()
var imageData: Data? = nil
imageManager.requestImageData(for: result, options: nil, resultHandler: { (data, string, orientation, dict) in
  imageData = data
})

4 个答案:

答案 0 :(得分:0)

将您的抓取过程保留在doInBackground的{​​{1}}方法中,然后显示它。并且仅获取首先需要的信息,例如,联系人姓名和ID。

请参阅此文章以获得更多说明: Fetching a large number of contacts

答案 1 :(得分:0)

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

一种可能的方法:

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

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

答案 2 :(得分: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);

如果可能,请进行号码检查,长度检查服务器端。在异步任务中执行。

答案 3 :(得分:0)

如果 1000 联系人 900 有电话号码,您当前正在查询数据库 901 次,您可以减少它只能两个查询

  1. 向我提供所有联系信息
  2. 给我所有电话号码
  3. 然后使用两者上的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);
    }