Android 如何使用内容解析器接收具有emai地址的本地联系人

Android 如何使用内容解析器接收具有emai地址的本地联系人,android,android-contacts,android-contentresolver,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 S

我正在开发一个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\u URI
进行了查询。此id用作外键,以在第二次查询中匹配联系人的电子邮件。解决方案是嵌套游标,运行时非常慢。对于100个联系人,查询需要两秒钟以上的时间才能匹配。这是使用async
CursorLoader
的原因,但如果可能的话,我希望避免使用它

有什么建议吗?提前谢谢

#编辑1:

不幸的是,这两种解决方案都没有实现预期的改进

例如,当我使用gmail应用程序向以前未知的地址发送新电子邮件时,该地址会显示在两个查询中,并带有联系人id,但不会显示在我的普通通讯簿中。这种“联系人”充斥着我的查询

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

#编辑2:

我发现一个有趣的标志
Contacts.IN_VISIBLE_GROUP+“=1”
。它似乎可以过滤不需要的地址。
有人有这方面的经验吗?我不想过滤太多。

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

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();

            }
        }
    }
}

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

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();

            }
        }
    }
}

我已经附上了在我的项目中使用的功能之一。最重要的是选择和选择参数

片段

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);
}

我已经附上了在我的项目中使用的功能之一。最重要的是选择和选择参数

片段

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);
}