Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 513
Roland Avatar asked Sep 09 '14 22:09

Roland


People also ask

Which method handle the request from a ContentProvider class?

A content provider component supplies data from one application to others on request. Such requests are handled by the methods of the ContentResolver class.

How do you read data from a content provider?

To retrieve data from a provider, your application needs "read access permission" for the provider. You can't request this permission at run-time; instead, you have to specify that you need this permission in your manifest, using the <uses-permission> element and the exact permission name defined by the provider.

How can I use custom content provider in another Android app?

After creating the content provider , specify the content provider in the manifest file. You can mention content provider using the tag. Inside the provider tag dont forget to mention the name and authorities attributes. This declaration should be ..

What is ContentResolver?

ContentResolver is used to select the right ContentProvider based on the ContentUris . A ContentUri may look like. content://com.android.contacts/contacts/3. content:// is called scheme and indicates that it is a ContentUri.


2 Answers

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.

like image 184
emerssso Avatar answered Sep 23 '22 00:09

emerssso


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);
like image 36
CChi Avatar answered Sep 22 '22 00:09

CChi