Подтвердить что ты не робот

Как отфильтровать результаты поиска контента в андроиде?

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

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

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

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

4b9b3361

Ответ 1

Вместо

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 '

и вы объединяете строки.

Ответ 2

Вы можете запросить поставщика контента с помощью ввода типа 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);

Обратите внимание, что вместо null у меня есть параметры, которые создают инструкцию sql.

RequestColumns - это данные, которые я хочу вернуть, и Contacts.Phones.NUMBER + "= '" + phoneNumber + "" - это предложение Where, поэтому я получаю имя и тип, где номер телефона соответствует

Ответ 3

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

См. документацию по методу в разделе ContentResolver и SQLite выражения.

Ответ 4

Фактически REGEXP с помощью службы содержимого журнала вызовов (означает, что функция 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"
);