How to use selection args to query specific rows from a contentprovider in android
Asked Answered
N

2

5

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.

Noway answered 9/9, 2014 at 22:11 Comment(0)
M
9

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:

  1. an =, since you want equality (you can also do other operators, of course)
  2. 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.

Mitzvah answered 9/9, 2014 at 22:30 Comment(2)
Thanks a Million :D to both you and CChi, this has been occupying my mind for the past 2 hours, i chose your answer because it was a bit more detailed, i wish i could upvote but i am new to stackexchange so unfortunately lack the reputation.Noway
Glad we could help. :)Mitzvah
J
3

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);
Johny answered 9/9, 2014 at 22:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.