121

How can I get all the names of the contacts in my Android and put them into array of strings?

frogatto
  • 28,539
  • 11
  • 83
  • 129
fsdf fsd
  • 1,301
  • 4
  • 13
  • 13
  • have You tried to use http://developer.android.com/reference/android/provider/ContactsContract.html ? – sandrstar Sep 24 '12 at 09:26
  • [check this](http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/3/) – Harish Sep 24 '12 at 09:30
  • 4
    possible duplicate of [How to get phone contacts in Android](http://stackoverflow.com/questions/4133163/how-to-get-phone-contacts-in-android) – NGLN Sep 24 '12 at 11:00
  • Added a small library on [Github Repository](https://github.com/nitiwari-dev/android-contact-extractor) to fetch contacts – Nitesh Tiwari May 12 '17 at 09:55

10 Answers10

201

Try this too,

private void getContactList() {
    ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);

    if ((cur != null ? cur.getCount() : 0) > 0) {
        while (cur != null && 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);
                while (pCur.moveToNext()) {
                    String phoneNo = pCur.getString(pCur.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));
                    Log.i(TAG, "Name: " + name);
                    Log.i(TAG, "Phone Number: " + phoneNo);
                }
                pCur.close();
            }
        }
    }
    if(cur!=null){
        cur.close();
    }
}

If you need more reference means refer this link Read ContactList

Ahmad Shahwaiz
  • 1,432
  • 1
  • 17
  • 35
Aerrow
  • 12,086
  • 10
  • 56
  • 90
  • thanks for help, how can i show all the name in an ListView?(that i will can see all the contacts name in my phone in another windows)? thanks – fsdf fsd Sep 24 '12 at 09:50
  • http://stackoverflow.com/questions/5165599/how-to-show-phone-contacts-in-a-listview This is the thing you are looking for.. I know you would accept it as answer if I put copy paste code here... – Jigar Pandya Sep 24 '12 at 10:09
  • Why does everyone include the `if (cur.getCount() > 0) {`? Cursor is supposed to start *before* the first item. – chacham15 Jul 12 '14 at 07:36
  • Hello, I tried something similar, but it didn't work. Here is my question, I would really appreciate your help! :) http://stackoverflow.com/questions/35097844/get-contact-name/35098111#35098111 – Ruchir Baronia Jan 30 '16 at 05:07
  • 4
    For some reason this code gets each contact twice. Do you happen to know why? – Andrew No Mar 30 '16 at 01:51
  • 1
    @Aerrow some times get some contacts twice.Do you solve this issues? – Suman Apr 13 '16 at 12:47
  • 3
    do not forget to close the cursor! – MikeL Aug 03 '17 at 14:55
  • 26
    DO NOT use this code. It queries for all contacts, and then executes additional query for each single contact. Terrible performance - might take more than 10 seconds to run on a real device. – Vasiliy Nov 14 '17 at 12:19
  • I am getting always Zero(0) in `hasPhoneNumber` variable `int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));` because of that I cant get Phone Number.. please help me.. – Fra Red Mar 02 '19 at 14:58
  • Hey @MikeL, What if any new contact is added into the device, how to refresh the list i will get above to the new contact. Should i refresh the whole list every time on app launch ? – alphaguy Jun 02 '19 at 03:03
  • Can I get blocked contacts, blocked by the user? – Mateen Chaudhry May 07 '20 at 09:05
  • @MateenChaudhry yes you can, please user like Cursor c = getContentResolver().query(BlockedNumbers.CONTENT_URI, new String[]{BlockedNumbers.COLUMN_ID, BlockedNumbers.COLUMN_ORIGINAL_NUMBER, BlockedNumbers.COLUMN_E164_NUMBER}, null, null, null); for more https://source.android.com/devices/tech/connect/block-numbers – Aerrow Jun 07 '20 at 14:56
  • @AndrewNo you have to include the MIMETYPE you want in the selection argument. ContactContracts.Data.Minetype = ContactContracts.CommonDataTypes.Phone.ContentItemType – rial Jul 22 '20 at 22:45
  • 1
    @Vasiliy is right, if your contacts are less you maybe deceived it is fast, but problematic for actual users who have large contacts. – Aman Feb 16 '21 at 15:17
20

Get all contacts in less than a second and without any load in your activity. Follow my steps works like a charm.

ArrayList<Contact> contactList = new ArrayList<>();

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

private void getContactList() {
    ContentResolver cr = getContentResolver();

    Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
    if (cursor != null) {
        HashSet<String> mobileNoSet = new HashSet<String>();
        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);
                number = number.replace(" ", "");
                if (!mobileNoSet.contains(number)) {
                    contactList.add(new Contact(name, number));
                    mobileNoSet.add(number);
                    Log.d("hvy", "onCreaterrView  Phone Number: name = " + name
                            + " No = " + number);
                }
            }
        } finally {
            cursor.close();
        }
    }
}

Contacts


public class Contact {
public String name;
public String phoneNumber;

public Contact() {
}

public Contact(String name, String phoneNumber ) {
    this.name = name;
    this.phoneNumber = phoneNumber;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPhoneNumber() {
    return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
}

}

Benefits

  • less than a second
  • without load
  • ascending order
  • without duplicate contacts
DuDa
  • 3,718
  • 4
  • 16
  • 36
jay patoliya
  • 611
  • 7
  • 8
  • this should be accepted answer. because its so fast. thanks – Bilal Şimşek Sep 09 '21 at 07:34
  • This is extremely better. A key point to mention is that the big difference here is that the used uri for this optimized solution is `ContactsContract.CommonDataKinds.Phone.CONTENT_URI` which gives you an access to the `ContactsContract.CommonDataKinds.Phone.NUMBER` column directly. In the worse answer, you query the uri `ContactsContract.Contacts.CONTENT_URI` which doesn't give you an access to the `ContactsContract.CommonDataKinds.Phone.NUMBER` column so you'll have to run another query using the id for each contact to access it. – Mohamed Medhat Dec 22 '21 at 11:08
  • it is wonderful – mohsen Apr 12 '22 at 06:54
  • now this is perfect – Senith Umesha Jul 11 '22 at 03:15
  • ContactsContract.CommonDataKinds.Phone.CONTENT_URI contains SPAM numbers and syncronized google business numbers. Suppose that you have 100 numbers in your contacts list, you'll get 250 records by using ContactsContract.CommonDataKinds.Phone.CONTENT_URI. The reason is your numbers (100) + google business numbers(50) + spam numbers (100) = 250. So that you must use ContactsContract.Contacts.CONTENT_URI, this will give you 100 record in our example. Iterate on each record and make another cursor query for each record to get contact number from ContactsContract.CommonDataKinds.Phone.CONTENT_URI. – Mesut Oct 11 '22 at 07:56
  • For sorting use " COLLATE NOCASE ASC" for case insensitive – Saify Feb 08 '23 at 07:13
18

Get contacts info , photo contacts , photo uri and convert to Class model

1). Sample for Class model :

    public class ContactModel {
        public String id;
        public String name;
        public String mobileNumber;
        public Bitmap photo;
        public Uri photoURI;
    }

2). get Contacts and convert to Model

     public List<ContactModel> getContacts(Context ctx) {
        List<ContactModel> list = new ArrayList<>();
        ContentResolver contentResolver = ctx.getContentResolver();
        Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
        if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
                    Cursor cursorInfo = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
                    InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(ctx.getContentResolver(),
                            ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(id)));

                    Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(id));
                    Uri pURI = Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);

                    Bitmap photo = null;
                    if (inputStream != null) {
                        photo = BitmapFactory.decodeStream(inputStream);
                    }
                    while (cursorInfo.moveToNext()) {
                        ContactModel info = new ContactModel();
                        info.id = id;
                        info.name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                        info.mobileNumber = cursorInfo.getString(cursorInfo.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        info.photo = photo;
                        info.photoURI= pURI;
                        list.add(info);
                    }

                    cursorInfo.close();
                }
            }
            cursor.close();
        }
        return list;
    }
gunner_dev
  • 357
  • 2
  • 11
Masoud Siahkali
  • 5,100
  • 1
  • 29
  • 18
  • 4
    Awesome function, just need to add one more line to close the cursor after finished the first while clause. Thanks a lot – Tram Nguyen Feb 28 '17 at 14:50
  • 1
    storing all the bitmap can be a bad idea, for example you load 1000 of bitmap and user see only first 10. – Hitesh Sahu Apr 18 '19 at 12:13
17
public class MyActivity extends Activity 
                        implements LoaderManager.LoaderCallbacks<Cursor> {

    private static final int CONTACTS_LOADER_ID = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Prepare the loader.  Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(CONTACTS_LOADER_ID,
                                      null,
                                      this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // This is called when a new Loader needs to be created.

        if (id == CONTACTS_LOADER_ID) {
            return contactsLoader();
        }
        return null;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        //The framework will take care of closing the
        // old cursor once we return.
        List<String> contacts = contactsFromCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed.  We need to make sure we are no
        // longer using it.
    }

    private  Loader<Cursor> contactsLoader() {
        Uri contactsUri = ContactsContract.Contacts.CONTENT_URI; // The content URI of the phone contacts

        String[] projection = {                                  // The columns to return for each row
                ContactsContract.Contacts.DISPLAY_NAME
        } ;

        String selection = null;                                 //Selection criteria
        String[] selectionArgs = {};                             //Selection criteria
        String sortOrder = null;                                 //The sort order for the returned rows

        return new CursorLoader(
                getApplicationContext(),
                contactsUri,
                projection,
                selection,
                selectionArgs,
                sortOrder);
    }

    private List<String> contactsFromCursor(Cursor cursor) {
        List<String> contacts = new ArrayList<String>();

        if (cursor.getCount() > 0) {
            cursor.moveToFirst();

            do {
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                contacts.add(name);
            } while (cursor.moveToNext());
        }

        return contacts;
    }

}

and do not forget

<uses-permission android:name="android.permission.READ_CONTACTS" />
Artyom
  • 1,099
  • 15
  • 18
  • 1
    Nice use of CursorLoader. Do you know how to pull phone numbers from each of those contacts within a CursorLoader? – Felker Jun 12 '16 at 02:43
  • 1
    You can implement LoaderManager.LoaderCallbacks instead LoaderManager.LoaderCallbacks. Where 'Contact' is your custom entity. – Artyom Jun 12 '16 at 15:27
  • 1
    @Artyom Can you please explain how to get the phonenumber part a bit? – hushed_voice Apr 16 '18 at 09:59
6

Improving on the answer of @Adiii - It Will Cleanup The Phone Number and Remove All Duplicates

Declare a Global Variable

// Hash Maps
Map<String, String> namePhoneMap = new HashMap<String, String>();

Then Use The Function Below

private void getPhoneNumbers() {

        Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);

        // Loop Through All The Numbers
        while (phones.moveToNext()) {

            String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

            // Cleanup the phone number
            phoneNumber = phoneNumber.replaceAll("[()\\s-]+", "");

            // Enter Into Hash Map
            namePhoneMap.put(phoneNumber, name);

        }

        // Get The Contents of Hash Map in Log
        for (Map.Entry<String, String> entry : namePhoneMap.entrySet()) {
            String key = entry.getKey();
            Log.d(TAG, "Phone :" + key);
            String value = entry.getValue();
            Log.d(TAG, "Name :" + value);
        }

        phones.close();

    }

Remember in the above example the key is phone number and value is a name so read your contents like 998xxxxx282->Mahatma Gandhi instead of Mahatma Gandhi->998xxxxx282

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
DragonFire
  • 3,722
  • 2
  • 38
  • 51
3
Cursor contacts = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
String aNameFromContacts[] = new String[contacts.getCount()];  
String aNumberFromContacts[] = new String[contacts.getCount()];  
int i = 0;

int nameFieldColumnIndex = contacts.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
int numberFieldColumnIndex = contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

while(contacts.moveToNext()) {

    String contactName = contacts.getString(nameFieldColumnIndex);
    aNameFromContacts[i] =    contactName ; 

    String number = contacts.getString(numberFieldColumnIndex);
    aNumberFromContacts[i] =    number ;
i++;
}

contacts.close();

The result will be aNameFromContacts array full of contacts. Also ensure that you have added

<uses-permission android:name="android.permission.READ_CONTACTS" />

in main.xml

gunner_dev
  • 357
  • 2
  • 11
Jigar Pandya
  • 6,004
  • 2
  • 27
  • 45
  • thanks alot i will try it,if i have further questions i will ask you – fsdf fsd Sep 24 '12 at 09:42
  • thanks for help, how can i show all the name in an ListView?(that i will can see all the contacts name in my phone in another windows)? thanks – fsdf fsd Sep 24 '12 at 09:54
  • http://stackoverflow.com/questions/5165599/how-to-show-phone-contacts-in-a-listview This is the thing you are looking for.. I know you would accept it as answer if I put copy paste code here... – Jigar Pandya Sep 24 '12 at 10:08
  • 6
    This answer is wrong. `PhoneLookup.NUMBER` is not a column in `ContactsContract.Contacts.CONTENT_URI`, `numberFieldColumnIndex` always returning `-1`. – cprcrack Mar 30 '14 at 15:06
  • 2
    It should be like this: `Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null); while (phones.moveToNext()) { String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Pho‌​ne.DISPLAY_NAME)); String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NU‌​MBER)); } phones.close();` – user1510006 Jan 21 '16 at 14:42
  • Hello, I tried something similar, but it didn't work. Here is my question, I would really appreciate your help! :) http://stackoverflow.com/questions/35097844/get-contact-name/35098111#35098111 – Ruchir Baronia Jan 30 '16 at 05:07
  • 1
    @gunner_dev please write a new answer if you're sure this answer *including your edit* will work. – Bö macht Blau Jan 23 '18 at 19:55
2

This is the Method to get contact list Name and Number

 private void getAllContacts() {
    ContentResolver contentResolver = getContentResolver();
    Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
    if (cursor.getCount() > 0) {
        while (cursor.moveToNext()) {

            int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
            if (hasPhoneNumber > 0) {
                String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                Cursor phoneCursor = contentResolver.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id},
                        null);
                if (phoneCursor != null) {
                    if (phoneCursor.moveToNext()) {
                        String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

   //At here You can add phoneNUmber and Name to you listView ,ModelClass,Recyclerview
                        phoneCursor.close();
                    }


                }
            }
        }
    }
}
M Talha
  • 181
  • 1
  • 8
2
//GET CONTACTLIST WITH ALL FIELD...       

public ArrayList < ContactItem > getReadContacts() {
         ArrayList < ContactItem > contactList = new ArrayList < > ();
         ContentResolver cr = getContentResolver();
         Cursor mainCursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
         if (mainCursor != null) {
          while (mainCursor.moveToNext()) {
           ContactItem contactItem = new ContactItem();
           String id = mainCursor.getString(mainCursor.getColumnIndex(ContactsContract.Contacts._ID));
           String displayName = mainCursor.getString(mainCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

           Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
           Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);

           //ADD NAME AND CONTACT PHOTO DATA...
           contactItem.setDisplayName(displayName);
           contactItem.setPhotoUrl(displayPhotoUri.toString());

           if (Integer.parseInt(mainCursor.getString(mainCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
            //ADD PHONE DATA...
            ArrayList < PhoneContact > arrayListPhone = new ArrayList < > ();
            Cursor phoneCursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] {
             id
            }, null);
            if (phoneCursor != null) {
             while (phoneCursor.moveToNext()) {
              PhoneContact phoneContact = new PhoneContact();
              String phone = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
              phoneContact.setPhone(phone);
              arrayListPhone.add(phoneContact);
             }
            }
            if (phoneCursor != null) {
             phoneCursor.close();
            }
            contactItem.setArrayListPhone(arrayListPhone);


            //ADD E-MAIL DATA...
            ArrayList < EmailContact > arrayListEmail = new ArrayList < > ();
            Cursor emailCursor = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[] {
             id
            }, null);
            if (emailCursor != null) {
             while (emailCursor.moveToNext()) {
              EmailContact emailContact = new EmailContact();
              String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
              emailContact.setEmail(email);
              arrayListEmail.add(emailContact);
             }
            }
            if (emailCursor != null) {
             emailCursor.close();
            }
            contactItem.setArrayListEmail(arrayListEmail);

            //ADD ADDRESS DATA...
            ArrayList < PostalAddress > arrayListAddress = new ArrayList < > ();
            Cursor addrCursor = getContentResolver().query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = ?", new String[] {
             id
            }, null);
            if (addrCursor != null) {
             while (addrCursor.moveToNext()) {
              PostalAddress postalAddress = new PostalAddress();
              String city = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
              String state = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
              String country = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
              postalAddress.setCity(city);
              postalAddress.setState(state);
              postalAddress.setCountry(country);
              arrayListAddress.add(postalAddress);
             }
            }
            if (addrCursor != null) {
             addrCursor.close();
            }
            contactItem.setArrayListAddress(arrayListAddress);
           }
           contactList.add(contactItem);
          }
         }
         if (mainCursor != null) {
          mainCursor.close();
         }
         return contactList;
        }



    //MODEL...
        public class ContactItem {

            private String displayName;
            private String photoUrl;
            private ArrayList<PhoneContact> arrayListPhone = new ArrayList<>();
            private ArrayList<EmailContact> arrayListEmail = new ArrayList<>();
            private ArrayList<PostalAddress> arrayListAddress = new ArrayList<>();


            public String getDisplayName() {
                return displayName;
            }

            public void setDisplayName(String displayName) {
                this.displayName = displayName;
            }

            public String getPhotoUrl() {
                return photoUrl;
            }

            public void setPhotoUrl(String photoUrl) {
                this.photoUrl = photoUrl;
            }

            public ArrayList<PhoneContact> getArrayListPhone() {
                return arrayListPhone;
            }

            public void setArrayListPhone(ArrayList<PhoneContact> arrayListPhone) {
                this.arrayListPhone = arrayListPhone;
            }

            public ArrayList<EmailContact> getArrayListEmail() {
                return arrayListEmail;
            }

            public void setArrayListEmail(ArrayList<EmailContact> arrayListEmail) {
                this.arrayListEmail = arrayListEmail;
            }

            public ArrayList<PostalAddress> getArrayListAddress() {
                return arrayListAddress;
            }

            public void setArrayListAddress(ArrayList<PostalAddress> arrayListAddress) {
                this.arrayListAddress = arrayListAddress;
            }
        }

        public class EmailContact
        {
            private String email = "";

            public String getEmail() {
                return email;
            }

            public void setEmail(String email) {
                this.email = email;
            }
        }

        public class PhoneContact
        {
            private String phone="";

            public String getPhone()
            {
                return phone;
            }

            public void setPhone(String phone) {
                this.phone = phone;
            }
        }


        public class PostalAddress
        {
            private String city="";
            private String state="";
            private String country="";

            public String getCity() {
                return city;
            }

            public void setCity(String city) {
                this.city = city;
            }

            public String getState() {
                return state;
            }

            public void setState(String state) {
                this.state = state;
            }

            public String getCountry() {
                return country;
            }

            public void setCountry(String country) {
                this.country = country;
            }
        }
Coldfin Lab
  • 361
  • 3
  • 8
2
//In Kotlin     
private fun showContacts() {
        // Check the SDK version and whether the permission is already granted or not.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(
                requireContext(),
                Manifest.permission.READ_CONTACTS
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissions(
                arrayOf(Manifest.permission.READ_CONTACTS),
                1001
            )
            //After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
        } else {
            // Android version is lesser than 6.0 or the permission is already granted.
            getContactList()
        }
    }
    private fun getContactList() {
        val cr: ContentResolver = requireActivity().contentResolver
        val cur: Cursor? = cr.query(
            ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null
        )
        if ((if (cur != null) cur.getCount() else 0) > 0) {
            while (cur != null && cur.moveToNext()) {
                val id: String = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts._ID)
                )
                val name: String = cur.getString(
                    cur.getColumnIndex(
                        ContactsContract.Contacts.DISPLAY_NAME
                    )
                )
                if (cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
                    val pCur: Cursor? = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                        arrayOf(id),
                        null
                    )
                    pCur?.let {
                        while (pCur.moveToNext()) {
                            val phoneNo: String = pCur.getString(
                                pCur.getColumnIndex(
                                    ContactsContract.CommonDataKinds.Phone.NUMBER
                                )
                            )
                            Timber.i("Name: $name")
                            Timber.i("Phone Number: $phoneNo")
                        }
                        pCur.close()
                    }

                }
            }
        }
        if (cur != null) {
            cur.close()
        }
    }
ShehryarAhmed
  • 95
  • 1
  • 11
1

I am using this method, and it is working perfectly. It gets fav, picture, name, number etc. (All the details of the contact). And also it is not repetitive.

List

private static List<FavContact> contactList = new ArrayList<>();

Method to get contacts

@SuppressLint("Range")
public static void readContacts(Context context) {

    if (context == null)
        return;

    ContentResolver contentResolver = context.getContentResolver();

    if (contentResolver == null)
        return;

    String[] fieldListProjection = {
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
            ContactsContract.CommonDataKinds.Phone.NUMBER,
            ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
            ContactsContract.Contacts.HAS_PHONE_NUMBER,
            ContactsContract.Contacts.PHOTO_URI
            ,ContactsContract.Contacts.STARRED
    };
    String sort = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " ASC";
    Cursor phones = contentResolver
            .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI
                    , fieldListProjection, null, null, sort);
    HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();

    if (phones != null && phones.getCount() > 0) {
        while (phones.moveToNext()) {
            String normalizedNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));

            if (Integer.parseInt(phones.getString(phones.getColumnIndex(
                    ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {

                    int id = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
                    String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    int fav = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED));
                    boolean isFav;
                    isFav= fav == 1;

                    String uri = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
                    if(uri!=null){
                        contactList.add(new FavContact(id,isFav,uri,name,phoneNumber));
                    }
                    else{
                        contactList.add(new FavContact(id,isFav,name,phoneNumber));
                    }

                }
            }
        }
        phones.close();
    }
}

Model Class

public class FavContact{

    private int id;

    private boolean isFavorite;

    private String image;

    private String name;

    private String number;
   

    public FavContact(int id,boolean isFavorite, String image, String name, String number){
        this.id=id;
        this.isFavorite = isFavorite;
        this.image = image;
        this.name = name;
        this.number = number;
    }

    public FavContact(int id,boolean isFavorite, String name, String number){
        this.id=id;
        this.isFavorite = isFavorite;
        this.name = name;
        this.number = number;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isFavorite() {
        return isFavorite;
    }

    public void setFavorite(boolean favorite) {
        isFavorite = favorite;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

}

Adapter

public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.MyViewHolder> implements Filterable {

private final Context context;
private final List<FavContact> contactList;
private final List<FavContact> filterList;
private final OnMyOwnClickListener onMyOwnClickListener;
private final FavContactRepo favContactRepo;

public ContactAdapter(Application application,Context context, List<FavContact> contactList, OnMyOwnClickListener onMyOwnClickListener) {
    this.context = context;
    this.contactList = contactList;
    this.onMyOwnClickListener = onMyOwnClickListener;
    filterList = new ArrayList<>(contactList);
    favContactRepo = new FavContactRepo(application);
}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    final LayoutInflater inflater = LayoutInflater.from(context);
    @SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.design_fav_contact, null, false);
    return new MyViewHolder(view,onMyOwnClickListener);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    final FavContact obj = contactList.get(position);
    holder.tv_contact_name.setText(obj.getName());

    holder.tv_contact_number.setText(obj.getNumber());

    if(obj.getImage()==null){
        Picasso.get().load(R.drawable.ic_circle_fav_no_dp).fit().into(holder.img_contact);
    }
    else{
        Bitmap bp;
        try {
            bp = MediaStore.Images.Media
                    .getBitmap(context.getContentResolver(),
                            Uri.parse(obj.getImage()));
            Glide.with(context).load(bp).centerInside().into(holder.img_contact);
        } catch (IOException e) {
            e.printStackTrace();
            Picasso.get().load(R.drawable.ic_circle_fav_no_dp).fit().into(holder.img_contact);
        }

    }
    obj.setFavorite(favContactRepo.checkIfFavourite(obj.getId()));

    if(obj.isFavorite()){
        Picasso.get().load(R.drawable.ic_menu_favorite_true).into(holder.img_fav_true_or_not);
    }
    else{
        Picasso.get().load(R.drawable.ic_menu_favorite_false).into(holder.img_fav_true_or_not);
    }

}

@Override
public int getItemCount() {
    return contactList.size();
}

@Override
public long getItemId(int position) {
    return position;
}
@Override
public int getItemViewType(int position) {
    return position;
}

static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    CircleImageView img_contact;
    TextView tv_contact_name,tv_contact_number;
    ImageView img_fav_true_or_not;
    ImageView img_call;
    RecyclerView fav_contact_rv;

    OnMyOwnClickListener onMyOwnClickListener;
    public MyViewHolder(@NonNull View itemView, OnMyOwnClickListener onMyOwnClickListener) {
        super(itemView);
        img_contact = itemView.findViewById(R.id.img_contact);
        tv_contact_name = itemView.findViewById(R.id.tv_contact_name);
        img_fav_true_or_not = itemView.findViewById(R.id.img_fav_true_or_not);
        tv_contact_number = itemView.findViewById(R.id.tv_contact_number);
        img_call = itemView.findViewById(R.id.img_call);
        fav_contact_rv = itemView.findViewById(R.id.fav_contact_rv);

        this.onMyOwnClickListener = onMyOwnClickListener;
        img_call.setOnClickListener(this);
        img_fav_true_or_not.setOnClickListener(this);
        img_contact.setOnClickListener(this);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        onMyOwnClickListener.onMyOwnClick(getAbsoluteAdapterPosition(),view);
    }
}

public interface OnMyOwnClickListener{
    void onMyOwnClick(int position,View view);
}


@Override
public Filter getFilter() {
    return filteredList;
}

public Filter filteredList = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<FavContact> filteredList = new ArrayList<>();
        if (constraint == null || constraint.length() == 0) {
            filteredList=filterList;
        } else {
            String filterText = constraint.toString().toLowerCase().trim();
            for (FavContact item : filterList) {
                if (item.getName().toLowerCase().contains(filterText)
                        ||item.getNumber().toLowerCase().contains(filterText)) {
                    filteredList.add(item);
                }
            }

        }

        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }

    @SuppressLint("NotifyDataSetChanged")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        contactList.clear();
        contactList.addAll((ArrayList)results.values);
        notifyDataSetChanged();

    }
};

Demo

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103