2012-06-01 13 views
14

Nel mio progetto ottenere contatti richiede molto tempo per essere caricato.Come caricare tutti i contatti con il tempo minimo in Android

  • Quali sono modi per ridurre il tempo per inserire i contatti
  • Si supponga ci sono 1000 contatti nel telefono.
  • In questo momento sta prendendo più di 2 minuti per caricare tutti i contatti

Come posso ridurre il tempo per caricare i contatti? Qualsiasi pensiero?

Ho fatto riferimento al seguente collegamento durante la programmazione del metodo iniziale.

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

risposta

6

Tempo totale dipenderà quali campi si sta tentando di accedere dalla tabella Contatti. Accedere a un campo inferiore significa meno loop, meno elaborazione e quindi risultati più veloci.

anche per velocizzare il backup dei contatti operazione di recupero è possibile utilizzare il ContentProvideClient invece di chiamare query ContentResolver ogni volta. Questo vi farà una query la tabella specifica, piuttosto che l'esecuzione di query prima per la ContentProvider richiesto e poi a tavola.

creare un'istanza di ContentProviderClient

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

riutilizzare questo mCProviderClient per ottenere contatti (dati da qualsiasi ContentProvider) i dati sulla vostra chiamata. Ad esempio nel metodo seguente, accedo solo a un campo.

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

SOLUZIONE meglio qui .....

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

ACCLAMAZIONI ... :)

+1

questa è una soluzione intelligente, ma cosa succede se il contatto ha più numeri di telefono? –

+0

@Melbourne Lopes- stai leggendo solo il numero di telefono, come posso leggere l'e-mail insieme a quello. –

+0

Perché questa è una soluzione migliore? – Relm

3

per caricare i contatti con tempo mininum la soluzione ottimale è quello di utilizzare il concetto di proiezione e argomento di selezione durante l'interrogazione del cursore per i contatti.

questo può essere fatto in modo seguente

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

Con il metodo sopra ci sono voluti 400ms (meno di secondo) per caricare contatti dove come in modo normall era tenuto 10-12 sec.

Per i dettagli imformation questo post potrebbe aiutare come ho preso l'aiuto da esso http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html

+0

Dovrebbe essere VERAMENTE la risposta accettata. Wayyyyy più efficiente –

0

Penso che questa sia una soluzione migliore:

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

per utilizzarlo è necessario chiamare questo le linee volta :

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

e quando si desidera ottenere il nome del contatto per numero, utilizzare solo:

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

questo algoritmo è un po 'più veloce ...

2

carico dei contatti più velocemente come gli altri app.I hanno testato questo codice il suo bel lavoro e più veloce come le altre applicazioni nel raggio di 500 ms (entro mezzo secondo) Sono in grado di caricare 1000+ contatti.

Il tempo totale dipenderà dai campi a cui si sta tentando di accedere dalla tabella Contatti. Gestire la query in base ai propri requisiti non accedere ai campi indesiderati. Accedere a un campo inferiore significa meno loop, meno elaborazione e quindi risultati più veloci.

Accedere al tavolo di destra a contatto aiuta anche a ridurre i tempi di caricamento dei contatti.

ottimizzazione Query per caricare contatto più veloce usare 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 
    }; 

selezione e selezione argomento

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

Per ordinare i contatti alfabeticamente utilizzano seguente codice

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

seguito è il codice sorgente completo

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

    } 

È possibile utilizzare il codice seguente nel codice di cui sopra che ho commentato. È sufficiente associare il contatto singolo con il suo numero multiplo. Per ottenere tutto il numero associato al contatto singolo, utilizzare l'array nella classe 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); 

     } 

classe Object

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 
     }*/ 
    } 
}} 
Problemi correlati