0

Я выполняю итерацию через таблицу Contacts, и каждая итерация делает итерацию на столе Phone, поэтому она принимает приложение. 4 секунды, чтобы сделать список контактов для 243 контактов (без повторного набора номеров телефонов, которые он загружает мгновенно). Я уверен, что есть способ сделать это быстрее.Как я могу сделать этот запрос ContactsContract.Contact быстрее с помощью внутреннего запроса CommonDataKinds.Phone?

Уже сделаны прогнозы для получения только необходимых столбцов, но они не улучшились. Может быть, я должен улучшить SQLite запрос или итерацию каким-либо другим способом:

Contact realmContact = new Contact(); 

     Uri uri = Contacts.CONTENT_URI; 

     String[] projection = { 
       Contacts.LOOKUP_KEY, 
       Contacts.DISPLAY_NAME_PRIMARY, 
       Contacts.LAST_TIME_CONTACTED, 
       Contacts.HAS_PHONE_NUMBER 
     }; 

     String selection = "((" + CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " NOTNULL) AND (" 
       + Contacts.HAS_PHONE_NUMBER + "=1) AND (" 
       + CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " != ''))"; 

     Cursor phones = getActivity() 
       .getContentResolver() 
       .query(uri, projection, selection, null, null); 

     while (phones.moveToNext()) { 
      String id = phones.getString(phones.getColumnIndex(Contacts.LOOKUP_KEY)); 

      String name = phones.getString(phones.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY)); 

      String lastTimeContacted = phones.getString(phones.getColumnIndex(Contacts.LAST_TIME_CONTACTED)); 
      long data = Long.parseLong(lastTimeContacted); 
      String date = new SimpleDateFormat("dd/MM/yyyy | HH:mm").format(new Date(data)); 

      if (Integer.parseInt(phones.getString(phones.getColumnIndex(Contacts.HAS_PHONE_NUMBER))) > 0) { 
       Cursor pCur = getActivity().getContentResolver().query(
         CommonDataKinds.Phone.CONTENT_URI, 
         new String[]{CommonDataKinds.Phone.NUMBER}, 
         CommonDataKinds.Phone.LOOKUP_KEY + " = ?", 
         new String[]{id}, null); 

       int iterationCounter = 0; 
       String phoneNumber = ""; 
       while (pCur.moveToNext()) { 
        phoneNumber += iterationCounter == 0 ? 
          pCur.getString(pCur.getColumnIndex(CommonDataKinds.Phone.NUMBER)) 
          : "," + pCur.getString(pCur.getColumnIndex(CommonDataKinds.Phone.NUMBER)); 

        iterationCounter += 1; 
       } 
       realmContact.setNumber(phoneNumber); 
       Log.i("asd-number", phoneNumber); 
       pCur.close(); 
      } 
      realmContact.setId(id); 
      realmContact.setName(name); 
      realmContact.setLastTimeContacted(
        getActivity().getResources() 
          .getString(R.string.contacts_list_fragment_last_call) 
          + date); 
      realmContact.setIsBeingSaved(true); 
      _realm.insertOrUpdate(realmContact); 
+0

просто перебрать курсором для 'CommonDataKinds. Phone.CONTENT_URI' – pskink

+0

у них нет столбца 'display_name' –

+1

да у них есть:' ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME' – pskink

ответ

0

Как @pskink упоминалось в комментариях, вам необходимо запросить по Phone таблице. Чтобы получить список телефонов по контактам, вы можете поддерживать HashMap от contactId до List телефонов.

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

HashMap<Long, ArrayList<String>> phones = new HashMap<Long, ArrayList<String>>(); 
String[] projection = new String[] { Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER }; 
Cursor c = cr.query(Phone.CONTENT_URI, projection, null, null, null); 
while (c != null && c.moveToNext()) { 
    long contactId = c.getLong(0); 
    ArrayList<String> list = phones.get(contactId); 
    if (list == null) { 
     ArrayList<String> list = new ArrayList<String>(); 
     phones.put(contactId, list); 
    } 
    list.add(c.getString(1) + " " + c.getString(2)); 
}