【问题标题】:Android get all contacts telephone number in ArrayListAndroid获取ArrayList中的所有联系人电话号码
【发布时间】:2013-02-21 00:05:26
【问题描述】:

我正在尝试将所有联系人电话号码保存在 ArrayList 中,但我找不到方法。有没有办法让它们而不是用 ContactsContract 一个一个地挑选它们?

【问题讨论】:

标签: java android android-contacts phone-number


【解决方案1】:
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()) ;
    }

【讨论】:

  • contResv是ContentResolver的一个实例,可以通过调用android.content.Context类的getContentResolver()方法得到
  • 很好,但我不明白最内部的 while 循环中发生了什么。你总是在一次之后打破它。在我看来,您可以在那里使用 IF 代替..
  • 对于约 9000 个联系人的测试,这需要约 99 秒(MotoX,第一代)。所以几乎没用.. 你可以使用 Lorem Contacts 来生成一些假人并检查play.google.com/store/apps/…
  • "提供显式投影,以防止从存储中读取不会使用的数据。传递 null 将返回所有列,这是低效的。" (来自文档)
  • 循环内循环效率低下,当您处理许多联系人时,请尝试 mudit 的回答
【解决方案2】:

试试这个:

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

通过遍历光标,您可以将所有这些数据存储在您选择的任何数据结构中。

【讨论】:

  • 这是迄今为止最快的解决方案。
  • 我不明白为什么到处都能找到带有双循环的其他答案,而这个解决方案却干净得多!
【解决方案3】:

此代码的运行速度将比答案中的代码快得多,因为您无需对每个联系人进行额外查询。

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

【讨论】:

  • 这里有问题,您从不使用 PHONE_NUMBER。我认为你有一个 PHONE_CONTACT_ID,你应该有 PHONE_NUMBER
  • @GregEnnis 我现在无法检查,但我认为你是对的。我会编辑我的答案
【解决方案4】:

试试这个还可以获取所有联系人。

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

【讨论】:

    【解决方案5】:

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

    需要为此创建一个数据类

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

    }

    【讨论】:

      【解决方案6】:

      此方法经过优化,仅获取不同的联系人

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

      【讨论】:

        【解决方案7】:

        首先,创建一个用于存储联系人数据的模型类: 并在您的联系人中添加 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
            }
        
         
        

        【讨论】:

          猜你喜欢
          • 2011-01-22
          • 2013-05-19
          • 1970-01-01
          • 1970-01-01
          • 2014-03-30
          • 1970-01-01
          • 2015-04-01
          • 1970-01-01
          相关资源
          最近更新 更多