简体   繁体   中英

Android get all contacts telephone number in ArrayList

I am trying to save all contacts telephone numbers in an ArrayList but I cant find a way how. Is there a way to get them instead of picking them one by one with ContactsContract?

ContentResolver cr = mContext.getContentResolver(); //Activity/Application android.content.Context
    Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    if(cursor.moveToFirst())
    {
        ArrayList<String> alContacts = new ArrayList<String>();
        do
        {
            String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

            if(Integer.parseInt(cursor.getString(cursor.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 contactNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    alContacts.add(contactNumber);
                    break;
                }
                pCur.close();
            }

        } while (cursor.moveToNext()) ;
    }

Try this:

Cursor managedCursor = getContentResolver()
    .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
     new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER}, null, null,  Phone.DISPLAY_NAME + " ASC");

And by traversing through the cursor, you can store all this data in any data structure of your choice.

This code will work much faster than code in the answer, because you don't make additional query for each contact.

private static final String CONTACT_ID = ContactsContract.Contacts._ID;
private static final String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;

private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
private static final String PHONE_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;

public static ArrayList<String> getAll(Context context) {
    ContentResolver cr = context.getContentResolver();

    Cursor pCur = cr.query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            new String[]{PHONE_NUMBER, PHONE_CONTACT_ID},
            null,
            null,
            null
    );
    if(pCur != null){
        if(pCur.getCount() > 0) {
            HashMap<Integer, ArrayList<String>> phones = new HashMap<>();
            while (pCur.moveToNext()) {
                Integer contactId = pCur.getInt(pCur.getColumnIndex(PHONE_CONTACT_ID));
                ArrayList<String> curPhones = new ArrayList<>();
                if (phones.containsKey(contactId)) {
                    curPhones = phones.get(contactId);
                }
                curPhones.add(pCur.getString(pCur.getColumnIndex(PHONE_NUMBER)));
                phones.put(contactId, curPhones);
            }
            Cursor cur = cr.query(
                    ContactsContract.Contacts.CONTENT_URI,
                    new String[]{CONTACT_ID, HAS_PHONE_NUMBER},
                    HAS_PHONE_NUMBER + " > 0",
                    null,null);
            if (cur != null) {
                if (cur.getCount() > 0) {
                    ArrayList<String> contacts = new ArrayList<>();
                    while (cur.moveToNext()) {
                        int id = cur.getInt(cur.getColumnIndex(CONTACT_ID));
                        if(phones.containsKey(id)) {
                            contacts.addAll(phones.get(id));
                        }
                    }
                    return contacts;
                }
                cur.close();
            }
        }
        pCur.close();
    }
    return null;
}

Try this also get all contacts.

Cursor cursor = context.getContentResolver().query(Phone.CONTENT_URI, null , null , null,
                        "upper("+Phone.DISPLAY_NAME + ") ASC");

in kotlin try this to get all contacts

fun getContacts(ctx: Context): List<ContactModel>? {
    val list: MutableList<ContactModel> = ArrayList()
    val contentResolver = ctx.contentResolver
    val cursor: Cursor? =
        contentResolver.query(
            ContactsContract.Contacts.CONTENT_URI, null,
            null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
        )
    if (cursor!!.count > 0) {
        while (cursor.moveToNext()) {
            val id =
                cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
            if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
                val cursorInfo: Cursor? = contentResolver.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                    arrayOf(id),
                    null
                )
                val inputStream: InputStream? =
                    ContactsContract.Contacts.openContactPhotoInputStream(
                        ctx.contentResolver,
                        ContentUris.withAppendedId(
                            ContactsContract.Contacts.CONTENT_URI,
                            id.toLong()
                        )
                    )
                val person: Uri =
                    ContentUris.withAppendedId(
                        ContactsContract.Contacts.CONTENT_URI,
                        id.toLong()
                    )
                val pURI: Uri = Uri.withAppendedPath(
                    person,
                    ContactsContract.Contacts.Photo.CONTENT_DIRECTORY
                )
                var photo: Bitmap? = null
                if (inputStream != null) {
                    photo = BitmapFactory.decodeStream(inputStream)
                }
                while (cursorInfo!!.moveToNext()) {
                    val info = ContactModel()
                    info.setId(id)
                    info.setName(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)))

                    info.setMobileNumber(
                        cursorInfo.getString(
                            cursorInfo.getColumnIndex(
                                ContactsContract.CommonDataKinds.Phone.NUMBER
                            )
                        )
                    )

                    photo?.let { info.setPhoto(it) }
                    info.setPhotoURI(pURI)
                    list.add(info)
                }
                cursorInfo.close()
            }
        }
        cursor.close()
    }
    return list
}

Need to create one data class for this

class ContactModel {
@SerializedName("id")
private var id: String = ""

@SerializedName("name")
private var name: String? = ""

@SerializedName("mobileNumber")
private var mobileNumber: String? = ""

@SerializedName("photo")
private var photo: Bitmap? = null

@SerializedName("photoURI")
private var photoURI: Uri? = null


fun getId(): String {
    return id
}

fun setId(id: String) {
    this.id = id
}

fun getName(): String? {
    return name
}

fun setName(name: String) {
    this.name = name
}

fun getMobileNumber(): String? {
    return mobileNumber
}

fun setMobileNumber(mobileNumber: String) {
    this.mobileNumber = mobileNumber
}

fun getPhoto(): Bitmap? {
    return photo
}

fun setPhoto(photo: Bitmap) {
    this.photo = photo
}

fun getPhotoURI(): Uri? {
    return photoURI
}

fun setPhotoURI(photoURI: Uri) {
    this.photoURI = photoURI
}


override fun toString(): String {
    return "ContactModel(id='$id', name=$name, mobileNumber=$mobileNumber, photo=$photo, photoURI=$photoURI)"
}

}

This method is optimized as well as fetch only distinct contacts

@RequiresApi(api = Build.VERSION_CODES.N)
private List<ModelContacts> getContacts() {

    ArrayList<ModelContacts> list = new ArrayList<>();
    Cursor cursor = this.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);

    cursor.moveToFirst();

    while (cursor.moveToNext()) {

        list.add(new ModelContacts(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
                , cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))));

    }
    cursor.close();

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

        List<ModelContacts> distinctList = list.stream().filter(distinctByKey(c -> c.getName()))
                .collect(Collectors.toList());
        
        return distinctList;
    }
    else {
       
        return list;
    }
}

@RequiresApi(api = Build.VERSION_CODES.N)
public static <T> Predicate<T> distinctByKey (final Function<? super T, Object> keyExtractor)
{
    Map<Object, Boolean> map = new ConcurrentHashMap<>();
    return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

Firstly, create a model class for storing Contacts Data: And add getAllContact(context) method in your contact: Don't forget to add user permision of Read Contacts in your manifest:

data class ContactModel(
    var name: String? = "",
    var mobileNumber: String? = "",
    var photoURI: Uri? = null
) 
class ContactsFragment : Fragment(R.layout.contacts_fragment) {
    private var _binding: ContactsFragmentBinding? = null
    private val binding get() = _binding
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = ContactsFragmentBinding.inflate(inflater, container, false)
        return binding?.root
    }

    @SuppressLint("Recycle")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if (!context?.let { checkIfAlreadyHavePermission(it) }!!) {

            context?.let { requestContactPermission(it) }
        } else {
            lifecycleScope.launch(Dispatchers.IO) {
                context?.let { getAllContacts(it) }
                Log.e("con", "con" + getAllContacts(requireContext()))


            }
        }


    }
fun getAllContacts(context: Context): List<ContactModel> {
        val contactList: ArrayList<ContactModel> = ArrayList()
        val contentResolver = context.contentResolver
        val notifier: Cursor? = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC")
        if (notifier!!.count > 0) {
            while (notifier.moveToNext()) {
                val id = notifier.getString(notifier.getColumnIndex(ContactsContract.Contacts._ID))
                if (notifier.getInt(notifier.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0)
                { val notifierInfo: Cursor? = contentResolver.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", arrayOf(id), null
                    )
                    val user: Uri =
                        ContentUris.withAppendedId(
                            ContactsContract.Contacts.CONTENT_URI,
                            id.toLong()
                        )
                    val userURI: Uri = Uri.withAppendedPath(
                        user,
                        ContactsContract.Contacts.Photo.CONTENT_DIRECTORY
                    )

                    while (notifierInfo!!.moveToNext()) {
                        val info = ContactModel()
                        info.name =
                            (notifier.getString(notifier.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)))

                        info.mobileNumber = (
                                notifierInfo.getString(
                                    notifierInfo.getColumnIndex(
                                        ContactsContract.CommonDataKinds.Phone.NUMBER
                                    )
                                )
                                )
                        contactList.add(info)

                    }
                    notifierInfo.close()
                }
            }
            notifier.close()
        }
        return contactList
    }

 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM