Home » Android » How to filter the results of content resolver in android?

How to filter the results of content resolver in android?

Posted by: admin April 23, 2020 Leave a comment

Questions:

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.

How to&Answers:

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.

Answer:

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

Answer:

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.

Answer:

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