How to filter the results of content resolver in android?

前端 未结 4 1435
再見小時候
再見小時候 2020-12-07 20:37

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

相关标签:
4条回答
  • 2020-12-07 21:35

    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

    0 讨论(0)
  • 2020-12-07 21:35

    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.

    0 讨论(0)
  • 2020-12-07 21:37

    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.

    0 讨论(0)
  • 2020-12-07 21:39

    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 讨论(0)
提交回复
热议问题