2

i use of this code that can get contact's number and contact's thumbnail , but this is not suitable and take to long to load and prepare contacts .

please help me to improve performance of this code :

List<Contact_Pojo> list = new ArrayList<Contact_Pojo>();
ContentResolver cr = getActivity().getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
        null, null, Phone.DISPLAY_NAME + " ASC");

int i = 0;
if (cur.moveToFirst()) {
    while (cur.moveToNext()) {

        Cursor phoneCursor = getActivity()
                .getContentResolver()
                .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER, },
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                + " = ?",
                        new String[] { cur.getString(cur
                                .getColumnIndex(ContactsContract.Contacts._ID)) },
                        null);

        if (phoneCursor.moveToFirst()) {
            Contact_Pojo personContact = new Contact_Pojo();
            /*
             * Id
             */
            personContact.setId(cur.getString(1));
            /*
             * Name
             */
            personContact
                    .setName(cur.getString(cur
                            .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
            /*
             * Photo ID
             */
            personContact
                    .setImageUrl(cur.getString(cur
                            .getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)));
            /*
             * Number
             */
            personContact.setNumber(phoneCursor.getString(0));
            //
            list.add(personContact);
        }

        phoneCursor.close();

    }
}

cur.close();
return list;

Update 4/4/2015

  • it is slow because it has getting all column from contact provider , in this table has +20 column that take many time .
Adnan Abdollah Zaki
  • 4,328
  • 6
  • 52
  • 58

3 Answers3

2

How about using AsyncTaskLoader,

write this code when you want to get contacts list

getLoaderManager() or getSupportLoaderManager().initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> loadingCallback)

public class LoadingCallback implements LoaderManager.LoaderCallbacks<Void> {
  @Override
  public Loader<Void> onCreateLoader(int i, Bundle bundle) {
    // Show your dialog;
    return new InitializeContactsTask(context, (ArrayList) contactList, mAdapter);
  }

  @Override
  public void onLoadFinished(Loader<Void> voidLoader, Void aVoid) {
    // UI Work here after background task and hide dialog.
  }

  @Override
  public void onLoaderReset(Loader<Void> voidLoader) {
  }
}

and

public class InitializeApplicationsTask extends AsyncTaskLoader<Void> {
  @Override
  protected void onStartLoading() {
      forceLoad();
  }

  @Override
  public Void loadInBackground() {
      // Query the contacts here and return null

      return null;
  }
}
Seho Noh
  • 96
  • 6
1

It's slow because, you are getting all column from contact provider, so use projection to get only those column which are required. like

String[] projection = {
ContactsContract.Contacts.DISPLAY_NAME // this is just example, add fields that required } ;

can you please tell me what is purpose of second query ? because here is my result of getting contact

enter image description here

and my method for getting all contact is

@SuppressLint("InlinedApi")
    public void readContacts() {

        long l1 = System.currentTimeMillis();

        Log.d("DEBUG",
                "starting readContacts() time " + l1);

        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                null, null, null);
        if (cur.getCount() > 0) {

            while (cur.moveToNext()) {

                Contact_pojo cp = new Contact_pojo();

                String Contact_Id = cur.getString(cur
                        .getColumnIndex(ContactsContract.Contacts._ID));
                String Contact_Name = cur
                        .getString(cur
                                .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                String photothumb = "";
                try {
                    photothumb = cur
                            .getString(cur
                                    .getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
                    if (photothumb != null
                            && !photothumb.toString().equalsIgnoreCase("")) {
                        cp.setImageUri(photothumb);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

                cp.setId(Contact_Id);

                cp.setName(Contact_Name);


Cursor phones = cr.query(Phone.CONTENT_URI, null,
                    Phone.CONTACT_ID + " = " + Contact_Id, null, null);
            while (phones.moveToNext()) {
                String number = phones.getString(phones
                        .getColumnIndex(Phone.NUMBER));
                int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));

                Log.d("DEBUG", "number " + number + " type " + type);
                cp.setNumber(number);

            }
            phones.close();
                contactList.add(cp);

            }
        }
        long l2 = System.currentTimeMillis();
        Log.d("DEBUG",
                "Finished readContacts() time " + l2);
        Log.d("DEBUG","Total contact loaded "+contactList.size()+" within "+ (l2 - l1) + "ms");

    }
Vishal Makasana
  • 960
  • 2
  • 7
  • 15
0

Don't use double query, this is taking too much time if device have lots of contacts and it's not working in some device also...

You can also fetch contact with single query..

Use below code..

public void fetchContacts() 
    {

        String[] projection = new String[] {
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER,
                ContactsContract.CommonDataKinds.Phone.NUMBER,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID};



        String _ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
        String DISPLAY_NAME =  Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME;
        String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;

        Cursor cursor = mActivity.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                projection, ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER + "=?", new String[] { "1" },
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);

        System.out.println("contact size.."+cursor.getCount());

        if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {

                String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
                String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));
                String phoneNumber = cursor.getString(cursor.getColumnIndex(NUMBER));



                System.out.println(" name : "+name);
                System.out.println(" number : "+phoneNumber);

            }
        }
    }

Check below links for get contact photo.

ContactsContract.Contacts.Photo

Getting a Photo from a Contact

Community
  • 1
  • 1
Niranj Patel
  • 32,980
  • 10
  • 97
  • 133
  • Great Answer but , for fetching photo from contact , this code do what my code do . is it similar to my code or not ? , because i use double query and your code use single query for get name and number and about photo , you use another query – Adnan Abdollah Zaki Apr 09 '15 at 10:36
  • @adnan9011 I updated my answer, please check it just added this line **String image = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));** – Niranj Patel Apr 09 '15 at 10:45
  • Thanks , let me check it . – Adnan Abdollah Zaki Apr 09 '15 at 11:04
  • it dosen't work . `cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)` return `-1` , because this column doesn't exist on `ContactsContract.CommonDataKinds.Phone.CONTENT_URI` table – Adnan Abdollah Zaki Apr 09 '15 at 12:30