从多个联系人号码列表中选择一个联系人号码

Posted

技术标签:

【中文标题】从多个联系人号码列表中选择一个联系人号码【英文标题】:Select one contact number from a list of multiple contact numbers 【发布时间】:2021-07-06 19:12:33 【问题描述】:

我只想在cursor 的帮助下从特定用户的联系电话列表中获取第一个联系电话。这是我的代码:

private ArrayList<ArrayList<String>> getAllContacts() 

        ArrayList<ArrayList<String>> nameList = new ArrayList<ArrayList<String>>();
        ArrayList<String> person=new ArrayList<>();
        ArrayList<String> number=new ArrayList<>();
        ArrayList<String> temp=new ArrayList<>();
        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));
                person.add(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);

                    if(pCur.getCount()==1) 
                        while (pCur.moveToNext()) 
                            String phoneNo = pCur.getString(pCur.getColumnIndex(
                                    ContactsContract.CommonDataKinds.Phone.NUMBER));
                            number.add(phoneNo);
                        
                    
                    else
                        while (pCur.moveToNext()) 
                            String phoneNo = pCur.getString(pCur.getColumnIndex(
                                    ContactsContract.CommonDataKinds.Phone.NUMBER));
                            temp.add(phoneNo);
                        
                        number.add(temp.get(0));
                        temp.clear();
                    
                    pCur.close();
                
            
        
        if (cur!=null) 
            cur.close();
        
        Log.d("contacts",String.valueOf(number.size())+" "+String.valueOf(person.size())); //the lists aren't of equal size

        if(person.size()==number.size())
            nameList.add(person);
            nameList.add(number);
        
        else
            //don't know what to do here
        
        return nameList;

    

但是,代码仍然会获取为单个用户保存的多个联系人号码,换句话说,person.size() 不等于 number.size()。我该怎么办?

【问题讨论】:

【参考方案1】:

数组大小不一样,因为并非所有联系人都有电话号码,您正在正确检查HAS_PHONE_NUMBER,并且只有在为真时,才会获取该联系人的电话号码 - 这意味着number.size() 将是person.size() on大多数手机。

我建议不要为姓名和电话保留单独的数组,而是使用一个带有代表一个人的简单 java 类的单个数组。

除此之外,您的代码效率非常低,因为您要执行大量查询,而您只能执行一个。

以下是上面两个建议的示例:

class Person 
    long id,
    String name,
    String firstPhone;

    public Person(id, name, firstPhone) 
        this.id = id;
        this.name = name;
        this.firstPhone = firstPhone;
    


Map<Long, Person> mapping = new HashMap<>(); // mapping between a contact-id to a Person object

String[] projection = Data.CONTACT_ID, Data.DISPLAY_NAME, Phone.NUMBER;

// query phones only
String selection = Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);

while (cur != null && cur.moveToNext()) 
    long id = cur.getLong(0);
    String name = cur.getString(1); // full name
    String phone = cur.getString(2); // phone

    Log.d(TAG, "got " + id + ", " + name + " - " + data);

    // only add a new object if we haven't seen this person before
    if (!mapping.containsKey(id)) 
        Person person = new Person(id, name, phone);
        mapping.put(id, person);
    

cur.close();

Array<Person> people = mapping.values();

编辑

Set<Long> ids = new HashSet<Long>();
Array<String> names = new ArrayList<String>();
Array<String> numbers = new ArrayList<String>();

String[] projection = Data.CONTACT_ID, Data.DISPLAY_NAME, Phone.NUMBER;

// query phones only
String selection = Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'";
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);

while (cur != null && cur.moveToNext()) 
    long id = cur.getLong(0);
    String name = cur.getString(1); // full name
    String phone = cur.getString(2); // phone

    Log.d(TAG, "got " + id + ", " + name + " - " + data);

    // only add a new object if we haven't seen this person before
    if (ids.add(id)) 
        names.add(name);
        numbers.add(phone);
    

cur.close();

【讨论】:

我想要两个单独的列表,其中一个包含人的姓名,另一个包含他们各自的联系电话。一个人应该只有一个联系电话。实际上我只想在列表视图中查看联系人的姓名,当按下特定姓名时,会向其各自的电话号码发送短信 我强烈建议不要有两个不同的列表(用于姓名和电话),而是一个包含一些对象的列表,但如果这是你的事,请参阅我上面的编辑

以上是关于从多个联系人号码列表中选择一个联系人号码的主要内容,如果未能解决你的问题,请参考以下文章

使用联系人选择器时从具有多个号码的用户中选择一个号码

从具有两个以上联系号码的联系人中仅选择一个号码

如何使用 android studio 从联系人列表中选择联系人号码?

光标与每个联系人一个电话号码

联系人列表仅使用意图 ContactsContract 显示一个电话号码

使用姓名和电话号码选择多个联系人