Android:联系人列表有重复的名字

Posted

技术标签:

【中文标题】Android:联系人列表有重复的名字【英文标题】:Android: Contact list has duplicate names 【发布时间】:2016-03-13 00:53:38 【问题描述】:

我有一个按排序顺序排列的联系人列表。但是在我的联系人列表中,名称与相同的号码重复。我认为问题是因为联系人列表与不同的帐户同步。

我检查哈希图。但是当我使用哈希映射时,结果不是按名称排序的。

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

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION,
  null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE NOCASE ASC");

if (cursor != null) 
    try 
        int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        String nameContact = cursor.getString(nameIndex);
    finally 
        cursor.close();
    

适配器

holder.name.setText(itemListPogo.get(position).getItemName());

任何人都可以帮助避免名称重复。

【问题讨论】:

请发布完整的代码适配器 【参考方案1】:

您看到重复的联系人,因为他们属于不同的帐户。即如果与 Facebook、WhatsApp 和 Google 帐户同步,相同的号码可以显示 3 次。你可以在这里找到更多信息android Account Manager

这就是您如何使用列 ContactsContract.RawContacts.ACCOUNT_TYPE 来过滤和检索仅与单个帐户关联的联系人。

String[] projection = new String[] 
                    ContactsContract.RawContacts._ID,
                    ContactsContract.RawContacts.ACCOUNT_TYPE,
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
                    ContactsContract.CommonDataKinds.Phone.NUMBER,
                    ContactsContract.CommonDataKinds.Photo.CONTACT_ID ;


            String selectionFields =  ContactsContract.RawContacts.ACCOUNT_TYPE + " = ?";
            String[] selectionArgs = new String[]"com.google";

            Cursor cursor =  getContentResolver().query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    projection,
                    selectionFields,
                    selectionArgs,
                    ContactsContract.Contacts.DISPLAY_NAME
            );

在此代码中,仅选择了与 Google 帐户关联的联系人。同样,如果您只想获取 WhatsApp 联系人列表,您可以将 "com.google" 替换为 "com.whatsapp"

【讨论】:

太好了@Zain,我现在可以过滤谷歌联系人了,如果设备上有多个谷歌账户,你知道如何过滤特定谷歌账户吗?【参考方案2】:

我会推荐你​​使用我的搜索结束的地方,它会给你最快的结果。

public static List<ContactDTO> getPhone(Context context) 
    List<ContactDTO> contactList = new ArrayList<ContactDTO>();
    ContentResolver cr = context.getContentResolver(); 
    String[] PROJECTION = new String[]  
        ContactsContract.RawContacts._ID, 
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
        ContactsContract.CommonDataKinds.Phone.NUMBER,
        ContactsContract.CommonDataKinds.Photo.CONTACT_ID ;

    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String filter = ""+ ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 and " + Phone.TYPE +"=" + Phone.TYPE_MOBILE;     
    String order = ContactsContract.Contacts.DISPLAY_NAME + " ASC";// LIMIT " + limit + " offset " + lastId + "";

    Cursor phoneCur = cr.query(uri, PROJECTION, filter, null, order);
    while(phoneCur.moveToNext()) 
        ContactDTO dto = new ContactDTO();
        dto.setName("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
        dto.setMobileNo("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
        dto.setPhotoUrl("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI)));
        dto.setContactId("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Photo.CONTACT_ID)));
        contactList.add(dto);
    
    phoneCur.close();

    return contactList;
 

ContactDTO 是 Simple POJO 类。

【讨论】:

我们无法从 Uri 检索电子邮件地址。他们有什么方法可以在一次查询中获取姓名、电话和电子邮件。【参考方案3】:

我认为问题是因为联系人列表与不同的同步 帐户。

是的,您的联系人列表同步了多个帐户。您应该使用帐户类型过滤联系人:ContactsContract.CommonDataKinds.Phone.ACCOUNT_TYPE_AND_DATA_SET。 您可以研究的帐户: https://developer.android.com/reference/android/accounts/AccountManager.html

【讨论】:

【参考方案4】:

您可以搜索 aggregated 联系人而不是所有 RawContacts。这只会为您提供 1 个具有给定名称的联系人(如在联系人应用程序中)。 示例(更改代码):

private static final String[] PROJECTION = new String[] 
    ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY, // Honeycomb+ should use this
    ContactsContract.CommonDataKinds.Phone.NUMBER
;

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(
    ContactsContract.Contacts.CONTENT_URI, 
    PROJECTION, 
    null, 
    null, 
    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " COLLATE NOCASE ASC");

if (cursor != null) 
    try 
        int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY);
        String nameContact = cursor.getString(nameIndex);
    finally 
        cursor.close();
    

来源:https://developer.android.com/reference/android/provider/ContactsContract.Contacts.html

【讨论】:

以上是关于Android:联系人列表有重复的名字的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Android 中的联系人列表中获取联系人?使用联系提供商

Android带索引联系人列表

如何使用 ListView 删除 Android Studio 显示中的重复联系人 [重复]

根据电话号码添加原始联系人时联系人重复

Android - 在联系人列表中搜索特定电话号码

有重复的联系人排序列表,为啥?