如何过滤android中内容解析器的结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2156363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to filter the results of content resolver in android?
提问by maxsap
I would like to get user contacts and then append some kind of regular expression and append them to a list view. I am currently able to get all the contacts via
我想获取用户联系人,然后附加某种正则表达式并将它们附加到列表视图中。我目前可以通过以下方式获取所有联系人
getContentResolver().query(People.CONTENT_URI, null, null, null, null);
getContentResolver().query(People.CONTENT_URI, null, null, null, null);
and then pass them to a custom class that extends SimpleCursorAdapter
.
然后将它们传递给一个扩展的自定义类SimpleCursorAdapter
。
So I would like to know how to get only the contacts that match a regular expression and not all of users contacts.
所以我想知道如何只获取与正则表达式匹配的联系人,而不是所有用户联系人。
回答by Diego Torres Milano
Instead of
代替
getContentResolver().query(People.CONTENT_URI, null, null, null, null);
you should use something like
你应该使用类似的东西
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);
this uses a parameterized request (using ?) and provides the actual values as a different argument, this avoids concatenation and prevents SQLinjection mainly if you are requesting the filter from the user. For example if you are using
这使用参数化请求(使用?)并提供实际值作为不同的参数,这主要是在您向用户请求过滤器时避免串联并防止SQL注入。例如,如果您正在使用
cursor = resolver.query(People.CONTENT_URI, projection,
People.NAME + " = '" + name + "'",
new String[] { sa1 }, null);
imagine if
想象一下,如果
name = "Donald Duck' OR name = 'Mickey Mouse") // notice the " and '
and you are concatenating the strings.
并且您正在连接字符串。
回答by Donal Rafferty
You can query the content provider with sql type input, the Query method is just a wrapper for an sql command.
您可以使用 sql 类型输入查询内容提供者,Query 方法只是 sql 命令的包装器。
Here is an example where I query for a Contacts name given a particular number
这是我查询给定特定号码的联系人姓名的示例
String [] requestedColumns = {
Contacts.Phones.NAME,
Contacts.Phones.TYPE
};
Cursor contacts = context.getContentResolver().query(
Contacts.Phones.CONTENT_URI,
requestedColumns,
Contacts.Phones.NUMBER + "='" + phoneNumber + "'",
null, null);
Note that instead of null I have parameters that build up the sql statement.
请注意,我有构建 sql 语句的参数,而不是 null。
The requestColumns are the data I want to get back and Contacts.Phones.NUMBER + "='" + phoneNumber + "'" is the Where clause, so I retrieve the Name and Type where the Phone Number matches
requestColumns 是我想要取回的数据,Contacts.Phones.NUMBER + "='" + phoneNumber + "'" 是 Where 子句,所以我检索了电话号码匹配的 Name 和 Type
回答by Yoni Samlan
You should be able to put a legal SQLite WHERE clause as the third argument to the query() method, including a LIKE, but there's no native REGEXP function in SQLite and Android doesn't seem to let you define your own. So depending how complex your needs are, a set of other SQLite conditions and LIKE expressions might do the trick.
您应该能够将合法的 SQLite WHERE 子句作为第三个参数添加到 query() 方法,包括 LIKE,但 SQLite 中没有原生 REGEXP 函数,Android 似乎不允许您定义自己的函数。因此,根据您的需求的复杂程度,一组其他 SQLite 条件和 LIKE 表达式可能会起作用。
See the documentation on the query methodunder ContentResolver and SQLite expressions.
请参阅ContentResolver 和SQLite 表达式下有关查询方法的文档。
回答by Andrew Tsvirko
Actually REGEXP with Calllog Content Provider works (means that regexp() function is defined for that content provider's Database https://sqlite.org/lang_expr.html#regexp)! But it is very slow: ~15 sec across ~1750 records.
实际上带有 Calllog Content Provider 的 REGEXP 有效(意味着为该内容提供者的数据库https://sqlite.org/lang_expr.html#regexp定义了 regexp() 函数)!但它非常慢:在 ~1750 条记录中 ~15 秒。
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"
);