Android — найти контакт по отображаемому имени

Я пытаюсь найти контакт по отображаемому имени. Цель состоит в том, чтобы открыть этот контакт и добавить к нему больше данных (в частности, больше телефонных номеров), но я изо всех сил пытаюсь даже найти контакт, который хочу обновить.

Это код, который я использую:

    public static String findContact(Context context) {

    ContentResolver contentResolver = context.getContentResolver();
    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI;
    String[] projection = new String[] { PhoneLookup._ID };
    String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " = ?";
    String[] selectionArguments = { "John Johnson" };
    Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);

    if (cursor != null) {
        while (cursor.moveToNext()) {
            return cursor.getString(0);
        }
    }
    return "John Johnson not found";
}

У меня есть контакт по имени «Джон Джонсон», но метод всегда возвращает «не найден». Я также пытался найти контакт только с одним именем, так что это не имеет значения.

Я подозреваю, что что-то не так с uri, аргументами выбора или выбора, потому что я не смог найти в Интернете ни одного примера поиска контактов с заданным отображаемым именем, и кажется, что отображаемое имя — это особый вид информации, отличный от, например, номер телефона.

Любые идеи, как я могу найти Джона Джонсона?


ОБНОВЛЕНИЕ: я узнал, как найти контакт по отображаемому имени:

        ContentResolver contentResolver = context.getContentResolver();
    Uri uri = Data.CONTENT_URI;
    String[] projection = new String[] { PhoneLookup._ID };
    String selection = StructuredName.DISPLAY_NAME + " = ?";
    String[] selectionArguments = { "John Johnson" };
    Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);

    if (cursor != null) {
        while (cursor.moveToNext()) {
            return cursor.getString(0);
        }
    }
    return "John Johnson not found";

Этот код возвращает идентификатор первого контакта с отображаемым именем «Джон Джонсон». В моем исходном коде у меня был неправильный uri и неправильный выбор в моем запросе.


person Bjarte Aune Olsen    schedule 08.03.2012    source источник


Ответы (3)


Измените URI вашего запроса.

Вы используете URI, предназначенный для фильтрации только телефонных номеров:

Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI;

Вам нужно использовать URI, который имеет доступ к столбцу display_name, например:

Uri uri = ContactsContract.Data.CONTENT_URI;

В Android SDK есть подробная разбивка того, какие URI использовать и когда их использовать. Документация:

  • Если вам нужно прочитать отдельный контакт, рассмотрите возможность использования CONTENT_LOOKUP_URI вместо CONTENT_URI.

  • Если вам нужно найти контакт по номеру телефона, используйте оптимизированный для этой цели PhoneLookup.CONTENT_FILTER_URI.

  • Если вам нужно найти контакт по частичному имени, например. чтобы создавать предложения с фильтрацией по мере ввода, используйте URI CONTENT_FILTER_URI.

  • Если вам нужно найти контакт по какому-либо элементу данных, например, адресу электронной почты, псевдониму и т. д., используйте запрос к таблице ContactsContract.Data. Результат будет содержать идентификатор контакта, имя и т. д.

person Joshua Pinter    schedule 10.05.2018

Я думаю, что проблема может быть вызвана установленной вами проекцией. Проекция используется, чтобы сообщить Android, какой столбец данных вы хотите запросить, тогда вы указываете только столбец id, чтобы отображаемое имя не возвращалось. Попробуйте удалить проекцию, чтобы увидеть, работает ли она.

-- Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);
++ Cursor cursor = contentResolver.query(uri, null, selection, selectionArguments, null);

person Frank Cheng    schedule 09.03.2012
comment
Спасибо за ответ, но нулевая проекция не помогла. Тот же код работает, когда я ищу номер телефона, поэтому можно использовать PhoneLookup._ID в качестве проекции, даже если я ищу совпадение в другом столбце. Если я правильно понял, проекция - это то, какие данные вы хотите получить из запроса, а не то, что вы ищете. Поэтому, если вы установите для проекции значение null, вы просто попросите получить все данные из соответствующих контактов, которые вы получаете из своего запроса. - person Bjarte Aune Olsen; 10.03.2012

Код ниже должен помочь

  if (displayName != null) {
        Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(displayName));
        String[] displayNameProjection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME };
        Cursor cur = context.getContentResolver().query(lookupUri, displayNameProjection, null, null, null);
        try {
            if (cur.moveToFirst()) {
                return true;
            }
        } finally {
            if (cur != null)
                cur.close();
        }
        return false;
    } else {
        return false;
    }

Ссылка: Статья о получении списка контактов

person dhakadamit    schedule 19.07.2017