2012-08-24 22 views
13

Tôi đang triển khai AutoCompleteTextView và tôi cần Tên và E-Mail của tất cả các liên hệ của mình. Tôi tìm thấy đoạn mã này mà tôi đang chạy không đồng bộ nhưng nó rất chậm.Nhận tên và email từ danh sách liên lạc rất chậm

ContentResolver cr = 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)); 

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

      while (emailCur.moveToNext()) { 

       String email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); 
        autoCompleteAdapter.add(name + " - " + email); 
      } 

      emailCur.close(); 
     } 
    } 
} 

Tôi đang thực hiện một loại truy vấn bên trong và tôi nghĩ đó là vấn đề. Có cách nào để điều chỉnh và làm cho nó nhanh hơn không?

+0

Bạn có quản lý để làm cho nó hoạt động không? –

+0

Bên ngoài 'if (cur.getCount()> 0)' là thừa và có thể bị xóa. – mdup

Trả lời

46
private static final String[] PROJECTION = new String[] { 
    ContactsContract.CommonDataKinds.Email.CONTACT_ID, 
    ContactsContract.Contacts.DISPLAY_NAME, 
    ContactsContract.CommonDataKinds.Email.DATA 
}; 

... 

ContentResolver cr = getContentResolver(); 
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, null, null, null); 
if (cursor != null) { 
    try { 
     final int contactIdIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID); 
     final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
     final int emailIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA); 
     long contactId; 
     String displayName, address; 
     while (cursor.moveToNext()) { 
      contactId = cursor.getLong(contactIdIndex); 
      displayName = cursor.getString(displayNameIndex); 
      address = cursor.getString(emailIndex); 
      ... 
     } 
    } finally { 
     cursor.close(); 
    } 
} 

vài lưu ý:

  • sử dụng chỉ ContactsContract.CommonDataKinds.Email.CONTENT_URI để có được thông tin bạn cần, xem ContactsContract.CommonDataKinds.Email để biết thông tin gì cột mà bạn có thể truy vấn
  • chiếu sử dụng để có được chỉ những cột mà bạn thực sự cần, giúp bạn tiết kiệm một số bộ nhớ và tăng hiệu suất truy vấn
  • chỉ nhận chỉ mục cột một lần, ngay trước chu kỳ while
+0

Hoạt động hoàn hảo. Cảm ơn –

+0

Làm việc như một nét duyên dáng ..:) – ADT

+0

thanx rất nhiều, cải thiện tuyệt vời –

5

Bạn không nên truy vấn trực tiếp các ContactsContract.Contacts

Make chỉ một truy vấn trên ContactsContract.CommonDataKinds với các loại dữ liệu email.

ContactsContract.CommonDataKinds.Email kế thừa rất nhiều giao diện khác mà bạn có thể sử dụng để tạo dự đoán của mình. (Xem hằng thừa kế từ tài liệu)

Ví dụ:

import android.provider.ContactsContract.CommonDataKinds.Email; 

[...] 

public static final String[] EMAILS_PROJECTION = new String[] { 
    Email._ID, 
    Email.DISPLAY_NAME_PRIMARY, 
    Email.ADDRESS 
}; 

để được sử dụng với

Email.CONTENT_URI 

Bạn có thể lấy rất nhiều thông tin (ví dụ như sử dụng id, tên người dùng hiển thị ...) trực tiếp từ loại dữ liệu email.

EDIT:

Tôi chỉ nhận ra bạn đang cố gắng để xây dựng một AutoCompleteTextView.

Bạn nên ghi đè runQueryOnBackgroundThread phương pháp và convertToString của CursorAdapter bạn và sử dụng Email.CONTENT_FILTER_URI

tôi thực sự mạnh mẽ đề nghị bạn để có một cái nhìn tại các mẫu ApiDemo.

Đặc biệt là AutoComplete4.java mẫu mà bạn có thể tìm thấy HERE.

+1

Cảm ơn Timothée, lời giải thích của bạn đã được thực hiện rất tốt. Quá tệ Tôi không thể đánh dấu cả hai câu trả lời là chính xác. Tôi nghĩ rằng câu trả lời của biegleux rất tốt (hoạt động cực tốt) cho những người dùng khác đang tìm kiếm một đoạn trích ngắn. –

1
ContentResolver cr = mContext.getContentResolver(); Cursor cursor= mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, "HAS_PHONE_NUMBER <> 0", null, null); if (cursor!= null) { final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); final int numberIndex = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); final int idIndex= cursor.getColumnIndex(ContactsContract.Contacts._ID); String displayName, number = null, idValue; while (cursor.moveToNext()) { 
    displayName = cursor.getString(displayNameIndex); 
    idValue= cursor.getString(idIndex); 
    Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id = '" + idValue + "'", null, null); 
    phones.moveToFirst(); 
    try { 
    number = phones.getString(phones.getColumnIndex("data1")); 
    } 
    catch (CursorIndexOutOfBoundsException e) 
    {` 
    } 
    phones.close(); 
    userList.add(new ContactModel(displayName , number , null , } 
Các vấn đề liên quan