【问题标题】:How to get non duplicated phone numbers from android contacts content provider如何从 android 联系人内容提供商获取不重复的电话号码
【发布时间】:2018-04-16 07:36:18
【问题描述】:

我正在尝试获取所有具有手机号码的联系人。 我能够获取联系人。但问题是它给了我重复的联系人。相同的电话号码出现了两次。

我使用以下代码获取联系人。

public static List<RawContact>  getAllContacts(Context context,Account account){
        Log.d(TAG, "*** Looking for local contacts with mobile number!!");
        String phoneNumber = null;
        String email = null;
        int numberOfContacts = 0;
        List<RawContact> newContacts = new ArrayList<RawContact>();
        Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
        String _ID = ContactsContract.Contacts._ID;
        String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
        String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;

        Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
        String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;

        List<RawContact> localNewContacts = new ArrayList<RawContact>();
        final ContentResolver contentResolver = context.getContentResolver();
        final Cursor cursor = contentResolver.query(CONTENT_URI,
                null,
                null,
                null,
                null);

        if(cursor.getCount()>0){
            numberOfContacts = 0;
            Log.d(TAG, "*** Looking for local contacts "+cursor.getCount());
            while(cursor.moveToNext()){
                String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
                String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
                int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
                final long rawContactId = cursor.getLong(DirtyQuery.COLUMN_RAW_CONTACT_ID);
                if (hasPhoneNumber > 0) {
                    //This is to read multiple phone numbers associated with the same contact
                    Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, ContactsContract.RawContacts.ACCOUNT_TYPE + " <> 'google' "+" AND "+ Phone_CONTACT_ID + " = ?", new String[]{contact_id}, null);
                    while (phoneCursor.moveToNext()) {
                        phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
                        Log.d(TAG,"Phone number is: "+phoneNumber);
                        RawContact rawContact = getRawContact(context, rawContactId);
                        Log.d(TAG, "Contact Name: " + rawContact.getBestName());
                        localNewContacts.add(rawContact);
                    }phoneCursor.close();
            }
            numberOfContacts++;
            Log.d(TAG, "numberOfContacts updated: "+numberOfContacts);
        }

    }
        return localNewContacts;
    }

如何解决这个问题

【问题讨论】:

标签: android android-contacts


【解决方案1】:

您收到重复的联系人,因为您实际上是在阅读 RawContacts,而不是联系人。多个RawContacts 可以并且将包含由单个Contact 代表的单个人的信息。

您需要对Phones 表进行一次查询,并使用从CONTACT_ID 到联系信息的HashMap 组织数据,这样您就不会得到重复。

联系人数据库分为三个主要表:

  1. Contacts - 每个条目代表一个联系人,并将一个或多个组合在一起 RawContacts
  2. RawContacts - 每个条目代表由某些 SyncAdapter(例如 Whatsapp、Google、Facebook、Viber)同步的联系人的数据,这会将多个数据条目分组
  3. Data - 有关联系人、电子邮件、电话等的实际数据。每一行都是属于单个 RawContact 的单个数据

您正在尝试对Contacts 表进行查询,并投影Data 表中的字段,但您不能这样做。

您可以使用类似下面的代码,只需将HashMap 转换为与您的ContactModel 对象一起使用:

Map<Long, List<String>> contacts = new HashMap<Long, List<String>>();

String[] projection = { Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3 };
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "')";
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);
    String mime = cur.getString(2); // type of data (e.g. "phone")
    String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
    int type = cur.getInt(4); // a numeric value representing type: e.g. home / office / personal
    String label = cur.getString(5); // a custom label in case type is "TYPE_CUSTOM"

    String labelStr = Phone.getTypeLabel(getResources(), type, label);
    Log.d(TAG, "got " + id + ", " + name + ", " + kind + " - " + data + " (" + labelStr + ")");

    // add info to existing list if this contact-id was already found, or create a new list in case it's new
    List<String> infos;
    if (contacts.containsKey(id)) {
        infos = contacts.get(id);
    } else {
        infos = new ArrayList<String>();
        infos.add("name = " + name);
        contacts.put(id, infos);
    }
    infos.add(kind + " = " + data + " (" + labelStr + ")");
}

【讨论】:

  • 得到了 411,在 Saravanan,亲切 - +44 7438 306573(手机)04-18 12:11:19.142 9560-9939/com.example.android.samplesync D/ContactManager:结果执行! 04-18 12:11:19.142 9560-9939/com.example.android.samplesync D/ContactManager:得到 411,在 Saravanan,种类 - +447438306573(手机)04-18 12:11:19.142 9560-9939/com。 example.android.samplesync D/ContactManager: 结果执行!!
  • 我得到这样的结果
  • 是的,您可以将这些手机格式化为 e164 并进行比较,以避免添加不同格式的相似手机。
  • 我正在尝试将联系人同步到我的服务器,但只需要在联系人中显示正在使用我们服务的联系人,我应该为所有联系人或仅使用我们服务的联系人提供源 ID 值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 2015-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2014-03-30
相关资源
最近更新 更多