Adnan Abdollah Zaki
Adnan Abdollah Zaki

Reputation: 4406

android get contacts detail such as number and thumbnail

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

Upvotes: 2

Views: 1589

Answers (3)

Niranj Patel
Niranj Patel

Reputation: 33248

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

Upvotes: 0

Vishal Makasana
Vishal Makasana

Reputation: 960

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

    }

Upvotes: 1

Seho Noh
Seho Noh

Reputation: 96

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

Upvotes: 2

Related Questions