简体   繁体   English

Android获取ArrayList中的所有联系人电话号码

[英]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.我正在尝试将所有联系人电话号码保存在 ArrayList 中,但我找不到方法。 Is there a way to get them instead of picking them one by one with ContactsContract?有没有办法让它们而不是用 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在 kotlin 中试试这个以获取所有联系人

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:首先,创建一个用于存储联系人数据的模型类:并在您的联系人中添加 getAllContact(context) 方法:不要忘记在清单中添加读取联系人的用户权限:

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
    }

 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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