如何在Android上快速查询联系人

如何在Android上快速查询联系人,android,android-contacts,Android,Android Contacts,在我的Android应用程序中,一个活动是显示用户手机中的联系人列表。 问题是该操作需要大约3秒钟的时间来执行,不用说这是完全不可接受的。 以下是我使用的代码: private List<Contact> retrieveContacts(ContentResolver contentResolver) { LinkedHashSet<Contact> contactSet = new LinkedHashSet<Contact>();

在我的Android应用程序中,一个活动是显示用户手机中的联系人列表。 问题是该操作需要大约3秒钟的时间来执行,不用说这是完全不可接受的。 以下是我使用的代码:

private List<Contact> retrieveContacts(ContentResolver contentResolver) {
        LinkedHashSet<Contact> contactSet = new LinkedHashSet<Contact>();
        List<Contact> listContacts = new ArrayList<Contact>();
        final Cursor cursor = contentResolver.query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                new String[] {
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER }, null,
                null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
        if (cursor == null);
        if (cursor.moveToFirst() == true) {
            do {
                final String name = cursor
                        .getString(cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                final String telephone = cursor
                        .getString(cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                Contact contact = new Contact(telephone, name, false, false);
                contactSet.add(contact);

            } while (cursor.moveToNext() == true);
        }

        if (cursor.isClosed() == false) {
            cursor.close();
        }
        for (Contact contact : contactSet){
            listContacts.add(contact);
        }
        return listContacts;
    }
private List retrieveContacts(ContentResolver ContentResolver){
LinkedHashSet contactSet=新LinkedHashSet();
List List contacts=new ArrayList();
最终游标=contentResolver.query(
ContactsContract.CommonDataTypes.Phone.CONTENT\u URI,
新字符串[]{
Contacts contract.CommonDataTypes.Phone.DISPLAY\u NAME,
ContactsContract.CommonDataTypes.Phone.NUMBER},空,
空,ContactsContract.CommonDataTypes.Phone.DISPLAY_NAME+“ASC”);
如果(游标==null);
if(cursor.moveToFirst()==true){
做{
最终字符串名=游标
.getString(游标
.getColumnIndex(ContactsContract.CommonDataTypes.Phone.DISPLAY_NAME));
最终字符串电话=光标
.getString(游标
.getColumnIndex(ContactsContract.CommonDataTypes.Phone.NUMBER));
联系人=新联系人(电话、姓名、假、假);
contactSet.add(contact);
}while(cursor.moveToNext()==true);
}
if(cursor.isClosed()==false){
cursor.close();
}
用于(触点:触点集){
listContacts.add(联系人);
}
返回列表联系人;
}
然后用retrieveContacts的结果填充ListView。 我之所以使用LinkedHashSet,是因为它不接受重复,并且保持了添加元素的顺序。(我需要保留该订单)


这是这样一个查询需要花费那么多时间的标准吗?有什么方法可以提高它的性能吗?

您可以使用一些优化来提高代码的性能。虽然我认为这是次要的

  • 获取一次名称和编号列后存储其索引
  • 可以使用ArrayList构造函数实现删除last for循环
  • 下面是我将如何编写此代码:

    private List<Contact> retrieveContacts(ContentResolver contentResolver) {
        LinkedHashSet<Contact> contactSet = new LinkedHashSet<Contact>();
        final Cursor cursor = contentResolver.query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                new String[] {
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER }, null,
                null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
        if (cursor == null);
        if (cursor.moveToFirst()) {
            int nameIndex = cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
            int phoneIndex = cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            do {
                final String name = cursor
                        .getString(nameIndex);
                final String telephone = cursor
                        .getString(phoneIndex);
                Contact contact = new Contact(telephone, name, false, false);
                contactSet.add(contact);
    
            } while (cursor.moveToNext());
        }
    
        if (!cursor.isClosed()) {
            cursor.close();
        }
    
        return new ArrayList<Contact>(contactSet);
    }
    
    private List retrieveContacts(ContentResolver ContentResolver){
    LinkedHashSet contactSet=新LinkedHashSet();
    最终游标=contentResolver.query(
    ContactsContract.CommonDataTypes.Phone.CONTENT\u URI,
    新字符串[]{
    Contacts contract.CommonDataTypes.Phone.DISPLAY\u NAME,
    ContactsContract.CommonDataTypes.Phone.NUMBER},空,
    空,ContactsContract.CommonDataTypes.Phone.DISPLAY_NAME+“ASC”);
    如果(游标==null);
    if(cursor.moveToFirst()){
    int nameIndex=游标
    .getColumnIndex(ContactsContract.CommonDataTypes.Phone.DISPLAY\u NAME);
    int phoneIndex=游标
    .getColumnIndex(ContactsContract.CommonDataTypes.Phone.NUMBER);
    做{
    最终字符串名=游标
    .getString(名称索引);
    最终字符串电话=光标
    .getString(电话索引);
    联系人=新联系人(电话、姓名、假、假);
    contactSet.add(contact);
    }while(cursor.moveToNext());
    }
    如果(!cursor.isClosed()){
    cursor.close();
    }
    返回新的ArrayList(contactSet);
    }
    
    “很多时间”?你有多少个联系人?有多少时间?我在问题中提到了3秒钟。在我的情况下,大约有100个联系人,我认为它没有那么大。嗯,它应该需要<100毫秒(0.1秒),而不是3秒,而不是1秒,请看我的回答:,它不仅可以获取姓名和电话号码,还可以获取电子邮件帐户。实际上,它确实改进了一些事情,现在执行大约需要1秒,这是非常好的!谢谢你。