通过 PHONE.CONTENT_URI 检索联系人会返回重复行

问题描述 投票:0回答:3

我正在尝试按帐户类型从我的原始联系人中检索电话号码。 使用下面的代码片段,

String SELECTION =
            ContactsContract.RawContacts.ACCOUNT_TYPE + "='" + Constants.ACCOUNT_TYPE + "'";

    ContentResolver cr = this.getContentResolver();
    Cursor cur = cr.query(ContactsContract.RawContacts.CONTENT_URI,
            null, SELECTION, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {
            String type = cur.getString(cur.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE));
            String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            //String phone = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            Log.e("number",name);
           // hasPhoneNumber(cur.getString(cur.getColumnIndex(ContactsContract.RawContacts._ID)));
        }
        cur.close();
    }

我可以检索与帐户类型相关的所有联系人,但是 hasPhoneNumber(String contactId) 返回空光标。

private boolean hasPhoneNumber(String id) {
    Cursor pCur = this.getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null,
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
            new String[]{id}, null);
    while (pCur.moveToNext()) {
        String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        phoneNo = phoneNo.replace(" ", "");
        if (Integer.parseInt(pCur.getString(
                pCur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
            Log.e("search", "found phone number");
            pCur.close();
            return true;
        }
        pCur.close();
    }
    return false;
}

但是,我决定使用 PHONE.CONTENT_URL 执行查询:

String SELECTION =
            ContactsContract.RawContacts.ACCOUNT_TYPE + "='" + Constants.ACCOUNT_TYPE + "'";

    ContentResolver cr = this.getContentResolver();
    Cursor cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, SELECTION, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {
            String type = cur.getString(cur.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE));
            String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String phone = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            Log.e("number",phone);
           // hasPhoneNumber(cur.getString(cur.getColumnIndex(ContactsContract.RawContacts._ID)));
        }
        cur.close();
    }

这按预期工作,只是我的联系人列表中只有 3 个联系人与此类查询匹配,但 while 循环运行了 6 次,每个数字显示两次。我怎样才能最好地实现这一点以及我做错了什么?

java android android-sqlite
3个回答
7
投票

您可以尝试在 URI 上使用 REMOVE_DUPLICATE_ENTRIES 参数:

Uri uri = Phone.CONTENT_URI.buildUpon()
        .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "1")
        .build();

但是,如果您有两个具有相同号码的原始联系人,我认为您无法消除重复项,因为上述查询参数只会使 Android 将

GROUP BY (RawContacts._ID, DATA1)
应用于查询。


0
投票

这是我在查询时删除重复项的方法

ContactsContract.CommonDataKinds.Phone.CONTENT_URI
。我有一个
ArrayList
保存所有联系人。请注意我对布尔值
addNewContact
所做的事情。我检查是否有另一个具有相同
CONTACT_ID
的联系人,如果没有,则会添加另一个联系人,但如果有,则会跳过添加该联系人。请在此处查看完整片段:

Cursor cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, null, null, null);

    cur.moveToPosition(-1);
    boolean addNewContact;
    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {
            String thumb = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
            String id = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
            String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

            if (allContacts==null)
                allContacts = new Vector<Contact>();


            addNewContact = true;
            for (Contact addedC:allContacts){
                if (addedC.id.equals(id))
                    addNewContact = false;
            }

            if (addNewContact) {
                Contact c = new Contact(name, id);

                if (thumb != null)
                    c.setThumb(cr, thumb);
                allContacts.add(c);
            }
        } 
    }

这是我的

Contact
课程:

public class Contact {
    String name;
    Bitmap thumb;
    String id;


    public Contact(String name, String id){
        this.name = name;
        this.id = id;
    }



    public void setThumb(ContentResolver cr, String  uri) {

        try {
            thumb = MediaStore.Images.Media.getBitmap(cr, Uri.parse(uri));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (thumb!=null)
            thumb = getCroppedBitmap(thumb);

    } 

0
投票

我认为它会根据 mimetype 返回多种类型的不同数据。

例如,如果

ContactsContract.Contacts.Data.MIMETYPE
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
,您可以从那里安全地获取电话号码。

但是如果它是一个不同的值,它的字段可能意味着其他东西,甚至是空。

所以,这取决于您的需求。如果您想收集所有信息,您需要检查每个 mimetype 并正确获取其数据。

© www.soinside.com 2019 - 2024. All rights reserved.