通过mime类型从电话簿中选择联系人

时间:2017-09-17 21:04:12

标签: android android-contacts contentobserver

我正在尝试通过MIME-TYPE从手机中提取联系人,因此我可以选择具有以下类型的联系人:

ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE

以下是我使用的方法:

public static ArrayList<Contact> fetchContactsFromPhone(@NonNull Context context) {
    ArrayList<Contact> contacts = new ArrayList<>();

    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;
    ContentResolver contentResolver = context.getContentResolver();
    Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);

    if (cursor != null && cursor.getCount() > 0) {

        while (cursor.moveToNext()) {

            String contact_id = cursor.getString(cursor.getColumnIndex(_ID));

            String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
            long hasPhoneNumber = Long.parseLong(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));

            if (hasPhoneNumber > 0) {

                Cursor phoneCursor = contentResolver.query(
                        PhoneCONTENT_URI,
                        null,
                        Phone_CONTACT_ID + " = " + contact_id + " AND " + ContactsContract.Data.MIMETYPE + " = " + "'"+ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE+"'"
                        , null, null);


                if (phoneCursor != null) {
                    while (phoneCursor.moveToNext()) {
                        Contact contact = new Contact();

                        String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
                        phoneNumber = phoneNumber.replaceAll("[()\\-\\s]", "").trim();

                        contact.setName(name);
                        contact.setPhoneNum(phoneNumber);

                        contacts.add(contact);
                    }
                    phoneCursor.close();
                }
            }
        }
        cursor.close();
    }

    //return data
    return contacts;
}

问题在于此查询,返回 ZERO 联系人。

任何想法为什么?

1 个答案:

答案 0 :(得分:1)

您正在查询包含数据行CommonDataKinds.Phone.CONTENT_URI = MIMETYPE的表格CommonDataKinds.Phone.CONTENT_ITEM_TYPE。 但是您要求使用MIMETYPE CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE的行,以便获得空光标。

这是对现有代码的轻松修复,但即使修复后,您的代码也很慢,它会在设备上的每个联系人上运行查询,这很容易就是数百个甚至成千上万的查询。如果您只需要获取所有联系人的姓名+号码,请尝试以下代码(一个查询以获取所有联系人):

ArrayList<Contact> contacts = new ArrayList<>();

// Make sure you import Phone from ContactsContract.CommonDataKinds.Phone

String[] projection = { Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER };
Cursor cur = cr.query(Phone.CONTENT_URI, projection, null, null, null);

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

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

    Contact contact = new Contact();

    contact.setName(name);
    contact.setPhoneNum(number);
    contacts.add(contact);
}

if (cur != null) {
    cur.close();
}

请注意,与您的代码类似,此代码可能会为每个联系人创建多个Contact个对象,以防联系人拥有多个电话。 如果每个联系人只需要一个Contact个对象,则需要修改Contact对象以包含电话列表,并将ArrayList<Contact>更改为HashMap<Long, Contact>,以便添加电话到现有对象而不是创建新对象。