开发者

How to filter the results of content resolver in android?

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);

and then pass them to a custom class that extends SimpleCursorAdapter.

So I would like to know how to get only the contacts that match a regular expression and not all of users contacts.


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 SQL injection mainly if you are requesting the filter from the user. For example if you are using

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.


You can query the content provider with sql type input, the Query method is just a wrapper for an sql command.

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.

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


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.

See the documentation on the query method under ContentResolver and SQLite expressions.


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.

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"
);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜