问题
i have constructed a basic content provider that stores SMS messages for learning purposes, so far i can read(without selection args), insert, update and delete.
However i have been stumped trying to figure out how to format the selection args for the WHERE clause in my provider:
Basicly my application needs to search for a specific timestamp (in long format) and return its _id
say your database has an entry like this that your trying to access:
2|1|1410293471300|test type 1||testing|0
and the entire database looks like this:
_id|CLIENTTRXID|CREATED_AT|TYPE|MESSAGEPRIO|MESSAGE|ACCEPTED
1|1|1410293471000|test type 1||testing|0
2|1|1410293471300|test type 1||testing|0
3|1|1410293471600|test type 1||testing|0
in sql the query would be "select _id from alerts where CREATED_AT=1410293471300;"
the code i was hoping would do the equivalent:
//normally i would get the string dynamically but to make it equal to the sql
String date = "1410293471300";
String[] selectionArgs = new String[]{ date };
Cursor cursor = getContext().getContentResolver().query(AlertContract.CONTENT_URI, null, AlertContract.Column.CREATED_AT, selectionArgs, AlertContract.DEFAULT_SORT);
seems to always produce the following error no matter what i try as selectionArgs
Exception caught﹕ Cannot bind argument at index 1 because the index is out of range.  The statement has 0 parameters.
here is the query method of my contentprovider:
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    qb.setTables( AlertContract.TABLE);
    switch (sURIMatcher.match(uri)) {
        case AlertContract.STATUS_DIR:
            break;
        case AlertContract.STATUS_ITEM:
            qb.appendWhere(AlertContract.Column.ID + "=" + uri.getLastPathSegment());
            break;
        default:
            throw new IllegalArgumentException( "illegal uri: " + uri);
    }
    String orderBy = (TextUtils.isEmpty(sortOrder)) ? AlertContract.DEFAULT_SORT : sortOrder;
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
    //register for uri changes
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    Log.d(TAG, "queried records: "+cursor.getCount());
    return cursor;
}
Presumably im missing something extremely obvious, and will feel quite silly for having posted this question.
But for the moment i would very much appreciate any help, as i am quite stumped.
回答1:
It looks like your issue is with your selection, rather than with your selectionArgs per se. The selection should be the whole query after the "where".  Here your selection is "CREATED_AT".  You need two more items to get it to work:
- an =, since you want equality (you can also do other operators, of course)
- a ?. This is where your selectionArgument will be inserted (each argument needs a?in the selection, so there should be the same number of?s in the selection as selectionArguments.
The end result should be more like "CREATED_AT = ?"
Check out the documentation and this tutorial for more info on how to correctly construct a ContentProvider query.
回答2:
When you query the content provider, try the following. The selection should be AlertContract.Column.CREATED_AT + "=?"
Cursor cursor = getContext().getContentResolver().query(AlertContract.CONTENT_URI, null, AlertContract.Column.CREATED_AT + "=?", selectionArgs, AlertContract.DEFAULT_SORT);
来源:https://stackoverflow.com/questions/25754360/how-to-use-selection-args-to-query-specific-rows-from-a-contentprovider-in-andro