Как получить локальные контакты с адресами электронной почты с помощью преобразователя содержимого

Я разрабатываю приложение для 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_URI с Contacts._ID. Этот идентификатор используется в качестве внешнего ключа для сопоставления контактов во втором запросе с их электронными письмами. Решением был вложенный курсор, а время выполнения было очень медленным. Для сотни контактов запрос соответствовал более двух секунд. Это причина для использования асинхронного CursorLoader, но я хочу избежать этого, если это возможно.

Какие-либо предложения? заранее спасибо

#Редактировать 1:

К сожалению, оба решения не архивируют желаемое улучшение.

Например, когда я пишу новое электронное письмо на ранее неизвестный адрес с помощью своего приложения Gmail, после этого адрес отображается в обоих запросах с идентификатором контакта, но не в моей обычной адресной книге. Такого рода «контакты» наводняют мой запрос.

Может ли это быть связано со значением ContactsContract.CommonDataKinds.Email.TYPE?

#Редактировать 2:

Я нашел интересный флаг Contacts.IN_VISIBLE_GROUP + "=1". Кажется, фильтрует нежелательные адреса. Есть ли у кого-нибудь опыт с этим? Я не хочу сильно фильтровать.


person user3604202    schedule 09.07.2014    source источник


Ответы (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();

            }
        }
    }
}
person Kalpesh Lakhani    schedule 09.07.2014

Я прикрепил одну из функций, используемых в моем проекте. Интересными будут аргументы выбора и выбора.

Фрагмент

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);
}
person amd    schedule 09.07.2014