2012-06-01 3 views
14

В моем проекте получение контактов занимает много времени, чтобы загрузить.Как загружать все контакты с минимальным временем в Android

  • Какие способы сократить время получения контактов
  • Предположим, есть 1000 контактов в телефоне.
  • Сейчас он занимает более 2 минут, чтобы загрузить все контакты

Как я могу уменьшить время загрузки контактов? Любые мысли?

При программировании начального метода я ссылался на следующую ссылку.

http://www.coderzheaven.com/2011/06/13/get-all-details-from-contacts-in-android/

ответ

6

Общее время будет зависеть от того, какие поля вы пытаетесь получить доступ из таблицы контактов. Доступ к меньшему полю означает меньшее количество циклов, меньше обработки и, следовательно, более быстрые результаты.

Кроме того, чтобы ускорить операцию выбора контактов, вы можете использовать ContentProvideClient вместо вызова запроса в ContentResolver каждый раз. Это заставит вас запрашивать определенную таблицу, а не запрашивать сначала для требуемого ContentProvider, а затем для таблицы.

Создать экземпляр ContentProviderClient

ContentResolver cResolver=context.getContextResolver(); 
ContentProviderClient mCProviderClient = cResolver.acquireContentProviderClient(ContactsContract.Contacts.CONTENT_URI); 

Затем повторно использовать этот mCProviderClient, чтобы получить Контакты (данные из любого ContentProvider) данные по вызову. Например, в следующем методе я получаю доступ только к одному полю.

private ArrayList<String> fetchContactsCProviderClient() 
    { 
     ArrayList<String> mContactList = null; 
     try 
     { 
      Cursor mCursor = mCProviderClient.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); 
      if (mCursor != null && mCursor.getCount() > 0) 
      { 
       mContactList = new ArrayList<String>(); 
       mCursor.moveToFirst(); 
       while (!mCursor.isLast()) 
       { 
        String displayName = mCursor.getString(mCursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); 
        mContactList.add(displayName); 
        mCursor.moveToNext(); 
       } 
       if (mCursor.isLast()) 
       { 
        String displayName = mCursor.getString(mCursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); 
        mContactList.add(displayName); 
       } 
      } 

      mCursor.close(); 
     } 
     catch (RemoteException e) 
     { 
      e.printStackTrace(); 
      mContactList = null; 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      mContactList = null; 
     } 

     return mContactList; 
    } 
8

ЛУЧШЕ РЕШЕНИЕ ЗДЕСЬ .....

private static final String[] PROJECTION = new String[] { 
     ContactsContract.CommonDataKinds.Phone.CONTACT_ID, 
     ContactsContract.Contacts.DISPLAY_NAME, 
     ContactsContract.CommonDataKinds.Phone.NUMBER 
    }; 
. 
. 
. 

ContentResolver cr = getContentResolver(); 
     Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null); 
     if (cursor != null) { 
      try { 
       final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
       final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); 

       String name, number; 
       while (cursor.moveToNext()) { 
        name = cursor.getString(nameIndex); 
        number = cursor.getString(numberIndex); 
       } 
      } finally { 
       cursor.close(); 
      } 
     } 

CHEERS ... :)

+1

это умное решение, но что, если контакт имеет несколько телефонных номеров? –

+0

@Melbourne Lopes - вы только читаете только номер телефона, как я могу читать идентификатор электронной почты вместе с этим. –

+0

Почему это лучшее решение? – Relm

3

Для загрузки контактов с Mininum время оптимальным решением является использование концепции проектирования и во время запроса курсора для контактов.

это может быть сделано следующим образом

void getAllContacts() { 
    long startnow; 
    long endnow; 

    startnow = android.os.SystemClock.uptimeMillis(); 
    ArrayList arrContacts = new ArrayList(); 

    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; 
    String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER; 
    Cursor cursor = ctx.getContentResolver().query(uri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.Contacts._ID}, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); 

    cursor.moveToFirst(); 
    while (cursor.isAfterLast() == false) { 

     String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
     String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
     int phoneContactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID)); 
     int contactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 
     Log.d("con ", "name " + contactName + " " + " PhoeContactID " + phoneContactID + " ContactID " + contactID) 

     cursor.moveToNext(); 
    } 
    cursor.close(); 
    cursor = null; 

    endnow = android.os.SystemClock.uptimeMillis(); 
    Log.d("END", "TimeForContacts " + (endnow - startnow) + " ms"); 
} 

С описанным выше способом потребовалось 400ms (меньше, чем второй), чтобы загрузить контакты, где, как и в Normall образом она занимает 10-12 сек.

Для деталей знаки В этот пост может помочь, как я принял помощь от него http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html

+0

Должен ДЕЙСТВИТЕЛЬНО быть принятым ответом. Wayyyyy более эффективен –

0

Я думаю, что это лучшее решение:

public ContentValues getAllContacts() { 
    ContentValues contacts = new ContentValues(); 
    ContentResolver cr = getContentResolver(); 
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); 

    if (cur != null && 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)); 

      if (cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) { 
       Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
         ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); 
       if (pCur != null) { 
        while (pCur.moveToNext()) { 
         String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
         contacts.put(phoneNo, name); 
        } 
        pCur.close(); 
       } 
      } 
     } 
     cur.close(); 
    } 
    return contacts; 
} 

для использования его необходимо вызвать эти строки раз :

ContentValues contacts = new ContentValues(); 
contacts = getAllContacts(); 

и если вы хотите получить контактное имя по номеру, просто используйте:

String number = "12345"; 
String name = (String) G.contacts.get(number); 

этот алгоритм немного быстрее ...

2

нагрузки Контакт быстрее, как и другие app.I проверили этот код его прекрасно работать и быстрее, как и другие приложения в пределах 500 мс (в пределах половины второго) Я способный загружать 1000 контактов.

Общее время зависит от того, какие поля вы пытаетесь получить из таблицы контактов. Измените свой запрос в соответствии с вашим требованием, не получив доступ к нежелательным полям. Доступ к меньшему полю означает меньшее количество циклов, меньшую обработку и, следовательно, более быстрые результаты.

Доступ к правой таблице в контакте также помогает уменьшить время загрузки контакта.

Оптимизация запросов для загрузки контакт более быстрее использовать projection

String[] projection = { 
      ContactsContract.Data.MIMETYPE, 
      ContactsContract.Data.CONTACT_ID, 
      ContactsContract.Contacts.DISPLAY_NAME, 
      ContactsContract.Contacts.PHOTO_URI, 
      ContactsContract.Contacts.STARRED, 
      ContactsContract.RawContacts.ACCOUNT_TYPE, 
      ContactsContract.CommonDataKinds.Contactables.DATA, 
      ContactsContract.CommonDataKinds.Contactables.TYPE 
    }; 

Выбор и выбор аргументов

String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)" + " AND " /*+ ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + 1 + "' AND "*/ + 
      ContactsContract.Data.HAS_PHONE_NUMBER + " = '" + 1 + "'"; 

    String[] selectionArgs = { 
      ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE, 
      ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, 
    }; 

Чтобы заказать контакты в алфавитном порядке используйте следующий код

try { 
     Collections.sort(listview_address, new Comparator<ContactBook>() { 
      @Override 
      public int compare(ContactBook lhs, ContactBook rhs) { 
       return lhs.name.toUpperCase().compareTo(rhs.name.toUpperCase()); 
      } 
     }); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

Ниже приводится полный исходный код

public void initeContacts() { 
    List<ContactBook> listview_address = new LinkedList<ContactBook>(); 
    SparseArray<ContactBook> addressbook_array = null; 
    { 
     addressbook_array = new SparseArray<ContactBook>(); 

     long start = System.currentTimeMillis(); 

     String[] projection = { 
       ContactsContract.Data.MIMETYPE, 
       ContactsContract.Data.CONTACT_ID, 
       ContactsContract.Contacts.DISPLAY_NAME, 
       ContactsContract.Contacts.PHOTO_URI, 
       ContactsContract.Contacts.STARRED, 
       ContactsContract.RawContacts.ACCOUNT_TYPE, 
       ContactsContract.CommonDataKinds.Contactables.DATA, 
       ContactsContract.CommonDataKinds.Contactables.TYPE 
     }; 

     String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)" + " AND " /*+ ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + 1 + "' AND "*/ + 
       ContactsContract.Data.HAS_PHONE_NUMBER + " = '" + 1 + "'"; 

     String[] selectionArgs = { 
       ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE, 
       ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, 
     }; 

     String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE; 

     Uri uri = null; 
     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { 
      uri = ContactsContract.CommonDataKinds.Contactables.CONTENT_URI; 
     } else { 
      uri = ContactsContract.Data.CONTENT_URI; 

     } 
     // we could also use Uri uri = ContactsContract.Data.CONTENT_URI; 
     // we could also use Uri uri = ContactsContract.Contact.CONTENT_URI; 

     Cursor cursor = getActivity().getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); 


     final int mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE); 
     final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID); 
     final int nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
     final int dataIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.DATA); 
     final int photo = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.PHOTO_URI); 
     final int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.TYPE); 
     final int account_type = cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE); 
     while (cursor.moveToNext()) { 
      int contact_id = cursor.getInt(idIdx); 
      String photo_uri = cursor.getString(photo); 
      String contact_name = cursor.getString(nameIdx); 
      String contact_acc_type = cursor.getString(account_type); 
      int contact_type = cursor.getInt(typeIdx); 
      String contact_data = cursor.getString(dataIdx); 
      ContactBook contactBook = addressbook_array.get(contact_id); 

      /* if (contactBook == null) { 
       //list contact add to avoid duplication 
       //load All contacts fro device 
       //to add contacts number with name add one extra veriable in ContactBook as number and pass contact_data this give number to you (contact_data is PHONE NUMBER) 
       contactBook = new ContactBook(contact_id, contact_name, getResources(), photo_uri, contact_acc_type, "phone number"); 
       addressbook_array.put(contact_id, contactBook); 
       listview_address.add(contactBook); 

      }*/ 

      String Contact_mimeType = cursor.getString(mimeTypeIdx); 
      //here am checking Contact_mimeType to get mobile number asociated with perticular contact and email adderess asociated 
      if (Contact_mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) { 

       if (contactBook != null) { 
        contactBook.addEmail(contact_type, contact_data); 
       } 

      } else { 
       if (contactBook == null) { 
        //list contact add to avoid duplication 
        //load All contacts fro device 
        //to add contacts number with name add one extra veriable in ContactBook as number and pass contact_data this give number to you (contact_data is PHONE NUMBER) 
        contactBook = new ContactBook(contact_id, contact_name, getResources(), photo_uri, contact_acc_type, "phone number"); 
        addressbook_array.put(contact_id, contactBook); 
        listview_address.add(contactBook); 

       } 
       // contactBook.addPhone(contact_type, contact_data); 


      } 


     } 

     cursor.close(); 


     try { 
      Collections.sort(listview_address, new Comparator<ContactBook>() { 
       @Override 
       public int compare(ContactBook lhs, ContactBook rhs) { 
        return lhs.name.toUpperCase().compareTo(rhs.name.toUpperCase()); 
       } 
      }); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

Вы можете использовать следующий код в приведенном выше коде, который я прокомментировал. Он объединяет единственный контакт с его многочисленным номером. Чтобы получить весь номер, связанный с массивом использования одного контакта в классе Object.

if (contactBook == null) { 
      //irst contact add to avoid duplication 
      //load All contacts fro device 
      contactBook = new ContactBook(contact_id, contact_name, getResources(), photo_uri, contact_acc_type, ""); 
      addressbook_array.put(contact_id, contactBook); 
      listview_address.add(contactBook); 
     } 

     String Contact_mimeType = cursor.getString(mimeTypeIdx); 
     //here am checking Contact_mimeType to get mobile number asociated with perticular contact and email adderess asociated 
     if (Contact_mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) { 

      contactBook.addEmail(contact_type, contact_data); 

     } else { 

      contactBook.addPhone(contact_type, contact_data); 

     } 

Класс объекта

public class ContactBook { 
public int id; 
public Resources res; 
public String name; 
public String photo; 
public String contact_acc_type; 
public SparseArray<String> emails; 
public SparseArray<String> phones; 
/* public LongSparseArray<String> emails; 
public LongSparseArray<String> phones;*/ 
public String header = ""; 


public ContactBook(int id, String name, Resources res, String photo, String contact_acc_type, String header) { 
    this.id = id; 
    this.name = name; 
    this.res = res; 
    this.photo = photo; 
    this.contact_acc_type = contact_acc_type; 
    this.header = header; 
} 

@Override 
public String toString() { 
    return toString(false); 
} 

public String toString(boolean rich) { 

    //testing method to check ddata 
    SpannableStringBuilder builder = new SpannableStringBuilder(); 
    if (rich) { 
     builder.append("id: ").append(Long.toString(id)) 
       .append(", name: ").append("\u001b[1m").append(name).append("\u001b[0m"); 
    } else { 
     builder.append(name); 
    } 

    if (phones != null) { 
     builder.append("\n\tphones: "); 
     for (int i = 0; i < phones.size(); i++) { 
      int type = (int) phones.keyAt(i); 
      builder.append(ContactsContract.CommonDataKinds.Phone.getTypeLabel(res, type, "")) 
        .append(": ") 
        .append(phones.valueAt(i)); 
      if (i + 1 < phones.size()) { 
       builder.append(", "); 
      } 
     } 
    } 

    if (emails != null) { 
     builder.append("\n\temails: "); 
     for (int i = 0; i < emails.size(); i++) { 
      int type = (int) emails.keyAt(i); 
      builder.append(ContactsContract.CommonDataKinds.Email.getTypeLabel(res, type, "")) 
        .append(": ") 
        .append(emails.valueAt(i)); 
      if (i + 1 < emails.size()) { 
       builder.append(", "); 
      } 
     } 
    } 
    return builder.toString(); 
} 

public void addEmail(int type, String address) { 
    //this is the array in object class where i am storing contact all emails of perticular contact (single) 
    if (emails == null) { 
     // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
     emails = new SparseArray<String>(); 
     emails.put(type, address); 
     /*} else { 
      //add emails to array below Jelly bean //use single array list 
     }*/ 
    } 
} 

public void addPhone(int type, String number) { 
    //this is the array in object class where i am storing contact numbers of perticular contact 
    if (phones == null) { 
     // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
     phones = new SparseArray<String>(); 
     phones.put(type, number); 
     /* } else { 
      //add emails to array below Jelly bean //use single array list 
     }*/ 
    } 
}} 
Смежные вопросы