2013-07-22 119 views
1

我的應用程序有一個listView由設備上註冊的聯繫人填充,但是當我加載listView時,它需要太長時間!這裏是我的代碼:獲取Android聯繫人的詳細信息非常慢

public List<Contact> getContactsList(Context context, ContentResolver contentResolver) { 

    List<Contact> listContatos = new ArrayList<Contact>(); 
    Uri uri = ContactsContract.Contacts.CONTENT_URI; 

    Cursor cursorContacts = contentResolver.query(uri, null, null, null, ContactsContract.Contacts.DISPLAY_NAME + " COLLATE NOCASE ASC;"); 
    try { 
     // while there is a next contact, retrieves your data 
     while (cursorContacts.moveToNext()) { 

      Contact c = getContact(context, cursorContacts); 

      if (c != null) { 
       listContatos.add(c); 
      } 
     } 
    } finally { 

     // Closes Cursor 
     cursorContacts.close(); 
    } 
    return listContatos; 
} 





public Contact getContact(Context context, Cursor contactsCur) { 

    Contact c = new Contact(); 

    // get contact id 
    long id = contactsCur.getLong(contactsCur.getColumnIndexOrThrow(BaseColumns._ID)); 
    String strId = contactsCur.getString(contactsCur.getColumnIndex(BaseColumns._ID)); 

    // get contact name 
    String name = contactsCur.getString(contactsCur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));  

    boolean temFone = false; 
    // if return is different than 1, doesn't has phone number 
    temFone = "1".equals(contactsCur.getString(contactsCur.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER))); 
    if (temFone) { 
     contactsCur = context.getContentResolver().query(
       ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
       ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", 
       new String[] { strId }, null); 

     ArrayList<PhoneNumber> phones = new ArrayList<PhoneNumber>(); 
     while (contactsCur.moveToNext()) { 

      int idx = contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); 

      if (idx != -1) { 
       String phoneNumber = contactsCur.getString(contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
       int phonetype = contactsCur.getInt(contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); 
       String customLabel = contactsCur.getString(contactsCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL)); 
       String phoneLabel = (String) ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), phonetype, customLabel); 

       phones.add(new PhoneNumber(phoneLabel, phoneNumber));      
      } 
     } 
     c.setPhones(phones); 

     contactsCur.close(); 
    } else { 
     c.setPhones(null); 
    } 

    loadAddress(context, c, id); 
    c.setContactId(id); 
    c.setName(name); 
    loadEmails(context, c, id); 
    loadPhotoUri(context, c, id); 
    return c; 
} 







private void loadEmails(Context context, Contact c, long id) { 

    Cursor cursor = context.getContentResolver().query(
      ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, 
      ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id, 
      null, null); 

    ArrayList<ContactMail> emails = new ArrayList<ContactMail>(); 
    while (cursor.moveToNext()) { 
     int idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA); 

     if (idx != -1) { 
      String stremail = cursor.getString(idx); 

      int emailtype = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)); 
      String customLabel = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.LABEL)); 
      String emailLabel = (String) ContactsContract.CommonDataKinds.Email.getTypeLabel(context.getResources(), emailtype, customLabel); 

      if (!stremail.equals("")) 
       emails.add(new ContactMail(stremail, emailLabel)); 
     } 
    } 
    c.setEmails(emails); 
    cursor.close(); 

} 

private void loadAddress(Context context, Contact c, long id) { 

    Cursor cursor = context.getContentResolver().query(
      ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = " + id, null, null); 

    ArrayList<Address> addresses = new ArrayList<Address>(); 
    while (cursor.moveToNext()) { 
     int idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DATA); 

     if (idx != -1) {     
      String address = cursor.getString(idx); 

      int addresstype = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE)); 
      String customLabel = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.LABEL)); 
      String addressLabel = (String) ContactsContract.CommonDataKinds.StructuredPostal.getTypeLabel(context.getResources(), addresstype, customLabel); 

      if (!address.equals("")) 
       addresses.add(new Address(address, addressLabel, null)); 


     } 
    } 
    c.setAddresses(addresses); 
    cursor.close(); 
} 

public void loadPhotoUri(Context context, Contact c, long id) { 

    Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
        null, 
        ContactsContract.Data.CONTACT_ID 
          + "=" 
          + id 
          + " AND " 

          + ContactsContract.Data.MIMETYPE 
          + "='" 
          + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE 
          + "'", null, null); 

    while (cursor.moveToNext()) { 
     int idx = cursor 
       .getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.DATA); 

     if (idx != -1) { 
      Uri person = ContentUris.withAppendedId(
        ContactsContract.Contacts.CONTENT_URI, id); 
      c.setPhoto(Uri.withAppendedPath(person, 
        ContactsContract.Contacts.Photo.CONTENT_DIRECTORY)); 
      } 
     } 
    } 

它的工作就好了,完美,唯一的問題是,永遠需要得到所有聯繫人的信息的。我使用getContact方法獲取有關設備中每個聯繫人的所有詳細信息,而不是我在聯繫人列表中放入的getContactsList。聯繫人列表由listView的適配器使用。

在此先感謝!

對不起,有任何英語錯誤...

+0

這裏是最佳解決方案的所有聯繫..... http://stackoverflow.com/a/28690064/1881527 乾杯... 。:) –

回答

3

我有同樣的問題。必須顯示所有的聯繫人姓名和電話號碼 - 工作很好,但花了太長時間。

作爲新的Android開發的世界裏,我做了一些研究一下,發現下面的帖子:

這對我來說是非常有用的。

我認爲問題是你正在做一個內部查詢,所以它需要你永遠。 我的代碼的主要問題是多次獲取列索引(所以我將它改爲在while循環之前一次)以及我在代碼內部沒有非常清晰的內部查詢,並找到了一種方法把它拿出來。

嘗試使用該職位的例子,看看它是否有助於(希望這 - 因爲對我來說是完美的!)

好運

+0

謝謝,它真的幫助我!我的問題是與聯繫人的照片,我沒有找到一種方法來做得更快。現在我的實際問題是與聯繫人更新大聲笑。你知道這件事嗎? –

1

這裏是我快速的解決方案:

Cursor cursorPhones = getContentResolver().query(
    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
    new String[]{ 
     ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, 
     ContactsContract.CommonDataKinds.Phone.NUMBER, 
     ContactsContract.CommonDataKinds.Phone.TYPE, 
     ContactsContract.CommonDataKinds.Phone.LABEL 
    }, 
    ContactsContract.Contacts.HAS_PHONE_NUMBER + ">0 AND LENGTH(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ")>0", 
    null, 
    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME 
); 

while (cursorPhones.moveToNext()) { 

    String displayName = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
    String number = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
    int type = cursorPhones.getInt(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); 
    String label = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL)); 
    CharSequence phoneLabel = ContactsContract.CommonDataKinds.Phone.getTypeLabel(context.getResources(), type, label); 

} 

cursorPhones.close(); 
1

經過這麼多的研究,我發現這個解決方案100%的快速加載。

裝入有光標裝載機

String[] PROJECTION = new String[] { 
      ContactsContract.CommonDataKinds.Phone.CONTACT_ID, 
      ContactsContract.Contacts.DISPLAY_NAME, 
      ContactsContract.CommonDataKinds.Phone.NUMBER }; 
    ArrayList<ContactBean> listContacts = new ArrayList<>(); 
    CursorLoader cursorLoader = new CursorLoader(context, 
      ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, 
      null, null, "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME 
        + ")ASC"); 

    Cursor c = cursorLoader.loadInBackground(); 

    if (c.moveToFirst()) { 

     int Number = c 
       .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); 
     int Name = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 

     do { 

      try { 
       String phNumber = c.getString(Number); 
       String phName = c.getString(Name); 




      } catch (Exception e) { 

      } 

     } while (c.moveToNext()); 

     c.close(); 
    } 
相關問題