如何使用内容解析器接收包含电子邮件地址的本地联系人

时间:2014-07-09 11:47:40

标签: android android-contacts android-contentresolver

我正在开发Android应用,希望接收我的本地联系人。确切地说,我想显示所有具有电子邮件地址的联系人。我目前的方法看起来像这样

import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;

private static final String[] CONTACT_PROJECTION = new String[] {
 Email.CONTACT_ID,
 Contacts.DISPLAY_NAME_PRIMARY,
 Email.ADDRESS,
};

Cursor data = mResolver.query(Data.CONTENT_URI,
 CONTACT_PROJECTION,
 Data.MIMETYPE + "='" + Email.CONTENT_ITEM_TYPE + "'",
 null, Contacts.DISPLAY_NAME_PRIMARY + " ASC");

使用此查询的问题是,结果中包含的行与本地地址簿中的联系人不匹配。可能我之前使用过这些电子邮件地址,但没有将其保存到我的地址簿中。

我已经尝试了另一种方法,我使用Contacts.CONTENT_URIContacts._ID进行了查询。此ID用作外键,以将第二个查询中的联系人与其电子邮件进行匹配。解决方案是嵌套游标,运行时非常慢。对于一百个联系人,查询花了两秒多的时间来匹配。这是使用异步CursorLoader的原因,但我想尽可能避免使用它。

有什么建议吗?提前致谢

#Edit 1:

不幸的是,这两种解决方案都没有归档所需的改进。

例如,当我使用我的gmail应用程序将新电子邮件写入以前的未知地址之后,地址会显示在具有联系人ID但不在我的正常通讯簿中的查询中。这种"联系人"充斥我的疑问。

它是否与ContactsContract.CommonDataKinds.Email.TYPE的值相关?

#Edit 2:

我发现了一个有趣的旗帜Contacts.IN_VISIBLE_GROUP + "=1"。它似乎过滤了不需要的地址。 有人有经验吗?我不想过滤太多。

2 个答案:

答案 0 :(得分:2)

这就是我在我的应用中使用的内容:

public void readContacts(){
    ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);

    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {
            String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                System.out.println("name : " + name + ", ID : " + id);

                // get the phone number
                Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
                                       ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
                                       new String[]{id}, null);
                while (pCur.moveToNext()) {
                      String phone = pCur.getString(
                             pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                      System.out.println("phone" + phone);
                }
                pCur.close();


                // get email and type

               Cursor emailCur = cr.query(
                        ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
                        new String[]{id}, null);
                while (emailCur.moveToNext()) {
                    // This would allow you get several email addresses
                        // if the email addresses were stored in an array
                    String email = emailCur.getString(
                                  emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                    String emailType = emailCur.getString(
                                  emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));

                    System.out.println("Email " + email + " Email Type : " + emailType);
                }
                emailCur.close();

            }
        }
    }
}

答案 1 :(得分:1)

我附上了项目中使用的一个功能。兴趣点是选择和选择args。

片段

selection = ContactsContract.CommonDataKinds.Email.DATA + " != ?";
selectionArgs = new String[]{""};

这表示选择基于电子邮件数据,不应为空。

同样,您可以根据需要添加任何选择参数。

整个功能

 public Cursor getInitCursorLoader() {
    String[] PROJECTION = null;
    String selection = null;
    String[] selectionArgs = new String[0];
    String order = null;
    Uri contentURI = null;
    switch (mFriendType) {
        case EMAIL:
            PROJECTION = new String[]{
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.PHOTO_ID,
                    ContactsContract.CommonDataKinds.Email.TIMES_CONTACTED,
                    ContactsContract.CommonDataKinds.Email.DATA};
            selection = ContactsContract.CommonDataKinds.Email.DATA + " != ?";
            selectionArgs = new String[]{""};
            contentURI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
            order = ContactsContract.CommonDataKinds.Email.TIMES_CONTACTED + " DESC";
            break;
        case SMS:
            PROJECTION = new String[]{
                    ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.PHOTO_ID,
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.TIMES_CONTACTED,
                    ContactsContract.CommonDataKinds.Phone.NUMBER,
                    ContactsContract.CommonDataKinds.Phone.TYPE};
            selection = ContactsContract.CommonDataKinds.Phone.TYPE + " = ?";
            selectionArgs = new String[]{String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)};
            contentURI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
            order = ContactsContract.CommonDataKinds.Phone.TIMES_CONTACTED + " DESC";
            break;
    }
    return mContext.getContentResolver().query(contentURI, PROJECTION, selection, selectionArgs, order);
}