Android: запрос ContactsContract, требуется более сложная строка выбора - PullRequest
3 голосов
/ 15 июня 2011

Я пытаюсь запросить ContactContract ContentProvider и получить данные, которые получит следующий алгоритм:

given a phone number (input), return record...:
if(recordNumber has 7 digits) {
    if('%recordNumber' LIKE 'inputNumber') {
        return recordDisplayName;
    }
} else if(recordNumber has 10 digits) {
    if('recordNumber' LIKE '%inputNumber') {
        return recordDisplayName;
    }
} else if(recordNumber == inputNumber) {
    return recordDisplayName;
}

, это работает при вызове запроса:

ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?"

но мне нужно что-то вроде этого:

"('%" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=7) OR ('" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '%?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=10)"

но я получаю ошибки времени выполнения каждый раз, когда я использую запрос с одной кавычкой.например, изменение:

ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?"

на:

ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE '?'"

приводит к ошибке времени выполнения «привязка или индекс столбца вне диапазона ...».так что это должна быть какая-то синтаксическая ошибка ... верно?Каков правильный синтаксис для ContentProvider запросов и / или как я могу получить набор результатов, который мне нужен от ContactsContract?

Ответы [ 2 ]

8 голосов
/ 16 июня 2011

запросов к ContentProviders немного отличаются и не прощают форматирования.для ContentProviders: если вы хотите использовать «%» в качестве символа подстановки, «%» должен быть объединен с аргументом в предложении WHERE, а не как часть самого предложения.

correct:

Cursor cursor = getContentResolver().query(
    ContactsContract.Data.CONTENT_URI, 
    null, 
    ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?",
    new String[] { "%"+number },
    null);

неверно:

Cursor cursor = getContentResolver().query(
    ContactsContract.Data.CONTENT_URI, 
    null, 
    ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE %?", 
    new String[] { number }, 
    null);

вышеприведенный «неправильный» оператор фактически полностью допустим для запросов SQLite, только не для запросов ContentProvider.

кроме того, одинарные кавычкиявляются синтаксической ошибкой в ​​предложении WHERE запроса ContentProvider (или связаны с аргументами в указанном предложении).

окончательный код:

if(number.length()==7) {
    cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, 
        ContactsContract.CommonDataKinds.Phone.NUMBER+" LIKE ?",
        //"('%" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=7) OR ('" + ContactsContract.CommonDataKinds.Phone.NUMBER+"' LIKE '%?' AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=10)",
        new String[] { "%"+number },
        null);
} else if(number.length()==10) {
    cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, 
        "("+ContactsContract.CommonDataKinds.Phone.NUMBER+"=? AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=7) OR ("+ContactsContract.CommonDataKinds.Phone.NUMBER+"=? AND LENGTH("+ContactsContract.CommonDataKinds.Phone.NUMBER+")=10)",
        new String[] { number.substring(3), number },
        null);
} else {
    cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, 
        ContactsContract.CommonDataKinds.Phone.NUMBER+"=?",
        new String[] { number },
        null);
}

этот код будет извлекать соответствующие отображаемые имена для телефонных номеров, которыесоответствует рассматриваемому номеру.
- если номер представляет собой 7-значный номер, мы извлекаем любые записи, чьи номера телефонов имеют последние 7 цифр (дефисы и специальные символы, кроме "*" и "#", поскольку они являются действительными телефонными символами) соответствует 7 цифрам рассматриваемого номера.
- если число представляет собой 10-значное число, оно возвращает любые записи, содержащие либо 7 цифри соответствуют последним 7 символам или содержат точное совпадение в случае, если запись имеет 10 цифр.
- если в рассматриваемом номере нет ни 7, ни 10 цифр, точное совпадение необходимо.

0 голосов
/ 29 декабря 2015

Используйте ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER вместо ContactsContract.CommonDataKinds.Phone.NUMBER

...