title: Getting android contacts details very slow
body: <p>My app has a listView populated by the contacts registered on the device, but when i load the listView, it takes too long! Here is my code:</p>
  
  <pre><code>public List&lt;Contact&gt; getContactsList(Context context, ContentResolver contentResolver) {
  
      List&lt;Contact&gt; listContatos = new ArrayList&lt;Contact&gt;();
      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&lt;PhoneNumber&gt; phones = new ArrayList&lt;PhoneNumber&gt;();
          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&lt;ContactMail&gt; emails = new ArrayList&lt;ContactMail&gt;();
      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&lt;Address&gt; addresses = new ArrayList&lt;Address&gt;();
      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));
              }
          } 
      } 
  </code></pre>
  
  <p>It's working just fine, perfectly, the only problem is that takes forever to get all contacts information's. I use the getContact method to get all detailed info about every contact in the device, than in getContactsList I put then in a list of Contact. The list of Contact is used by the adapter of the listView.</p>
  
  <p>Thanks in advance!</p>
  
  <p>Sorry about any english mistakes...</p>