Получение имени и электронной почты из списка контактов очень медленно

Я реализую AutoCompleteTextView, и мне нужно имя и E-Mail всех моих контактов. Я нашел этот фрагмент, что я работаю асинхронно, но это очень медленно.

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(); } } } 

Я выполняю свой внутренний запрос, и я думаю, что это проблема. Есть ли способ настроить его и сделать его быстрее?

Solutions Collecting From Web of "Получение имени и электронной почты из списка контактов очень медленно"

 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(); } } 

Несколько примечаний:

  • Используйте только ContactsContract.CommonDataKinds.Email.CONTENT_URI чтобы получить необходимую информацию, см. ContactsContract.CommonDataKinds.Email для информации, какие столбцы вы можете запросить
  • Используйте проекцию, чтобы получить только те столбцы, которые вам действительно нужны, вы сохраняете некоторую память и увеличиваете производительность запросов
  • Получать индексы столбцов только один раз, перед циклом while

Вы не должны напрямую запрашивать контакты ContactsContract.Contacts

Сделайте только один запрос в ContactsContract.CommonDataKinds с типом данных электронной почты.

ContactContract.CommonDataKinds.Email наследует множество других интерфейсов, которые вы можете использовать для построения своей проекции. (См. Унаследованные константы из документации)

Например :

 import android.provider.ContactsContract.CommonDataKinds.Email; [...] public static final String[] EMAILS_PROJECTION = new String[] { Email._ID, Email.DISPLAY_NAME_PRIMARY, Email.ADDRESS }; 

Для использования с

 Email.CONTENT_URI 

Вы можете получить много информации (например, идентификатор пользователя, отображаемое имя пользователя …) непосредственно из вида данных электронной почты.

РЕДАКТИРОВАТЬ:

Я просто понял, что вы пытаетесь создать AutoCompleteTextView.

Вы должны переопределить метод runQueryOnBackgroundThread и convertToString вашего CursorAdapter и использовать Email.CONTENT_FILTER_URI

Я действительно настоятельно рекомендую вам взглянуть на образцы ApiDemo .

Особенно образец AutoComplete4.java, который вы можете найти ЗДЕСЬ .

 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 , }