2010-01-28 3 views
31

Я хотел бы получить контакты с пользователем, а затем добавить какое-то регулярное выражение и добавить их в список. Я в настоящее время в состоянии получить все контакты черезКак фильтровать результаты поиска контента в андроиде?

getContentResolver().query(People.CONTENT_URI, null, null, null, null);

, а затем передать их в пользовательский класс, который расширяет SimpleCursorAdapter.

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

ответ

63

Вместо

getContentResolver().query(People.CONTENT_URI, null, null, null, null); 

вы должны использовать что-то вроде

final ContentResolver resolver = getContentResolver(); 
final String[] projection = { People._ID, People.NAME, People.NUMBER }; 
final String sa1 = "%A%"; // contains an "A" 
cursor = resolver.query(People.CONTENT_URI, projection, People.NAME + " LIKE ?", 
    new String[] { sa1 }, null); 

это использует параметризованный запрос (с использованием ?) и обеспечиваете фактические значения в качестве другого аргумента, это позволяет избежать конкатенации и предотвращает SQL инъекции в основном, если вы запрашиваете фильтр у пользователя. Например, если вы используете

cursor = resolver.query(People.CONTENT_URI, projection, 
    People.NAME + " = '" + name + "'", 
    new String[] { sa1 }, null); 

представьте себе, если

name = "Donald Duck' OR name = 'Mickey Mouse") // notice the " and ' 

и вы конкатенации строк.

+0

Спасибо всем за ваши отзывы. Я очень ценю это. – maxsap

+2

Очень приятное объяснение, спасибо большое! –

5

Вы можете запросить поставщика контента с использованием ввода типа sql, метод Query - это всего лишь оболочка для команды sql.

Вот пример, где я запрос на имя Контакты данный конкретный номер

String [] requestedColumns = { 
      Contacts.Phones.NAME, 
      Contacts.Phones.TYPE 
    }; 

Cursor contacts = context.getContentResolver().query(
      Contacts.Phones.CONTENT_URI, 
      requestedColumns, 
      Contacts.Phones.NUMBER + "='" + phoneNumber + "'", 
      null, null); 

Обратите внимание, что вместо того, чтобы нуль у меня есть параметры, которые строят в SQL заявление.

В requestColumns являются данные, которые я хочу, чтобы вернуться и Contacts.Phones.NUMBER + "=«+ PHONENUMBER + «»»это где положение, поэтому я получить имя и тип, где номер телефона соответствует

3

В качестве третьего аргумента для метода query() вы должны включить юридическое предложение SQLite WHERE, в том числе LIKE, но в SQLite нет встроенной функции REGEXP, и Android, похоже, не позволяет вам определить свой собственный. Таким образом, в зависимости от того, насколько сложны ваши потребности, множество других условий SQLite и выражения LIKE могут сделать трюк.

См. Документацию по адресу query method в разделе ContentResolver и SQLite expressions.

1

На самом деле REGEXP с провайдером контента Calllog работает (означает, что функция regexp() определена для этой базы данных поставщика контента https://sqlite.org/lang_expr.html#regexp)! Но это очень медленно: ~ 15 сек. За ~ 1750 записей.

String regexp = "([\\s\\S]{0,}" + 
TextUtils.join("||[\\s\\S]{0,}", numbers) + 
")"; 

cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, 
null, 
CallLog.Calls.NUMBER + " REGEXP ?", 
new String[]{regexp}, 
CallLog.Calls.DATE + " DESC" 
); 
Смежные вопросы