notifyChange with changed uri from contentProvider.update()

Shailendra Singh Rajawat picture Shailendra Singh Rajawat · Mar 25, 2013 · Viewed 9.8k times · Source

i have implemented update() of ContentProvider and notifying to observer using getContext().getContentResolver().notifyChange(uri, null);

my obvious need is that whenever just one row is effected i want to notify with row specific uri, but could not find way to do so. an additional query like "select id where selectionArgs" can do this but this will be a foolish way.

onchange(boolean, uri) get complete uri instead of specific row, easy to understand that this is because ContentProvider.update() is sending the same.

some code for more clarity

update() method of MyContentProvider

 @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

        Log.d("TAG", "update " + uri.getPath());

        int count = 0;
        switch (uriMatcher.match(uri)) {
        case BOOKS:
            count = booksDB.update(DATABASE_TABLE, values, selection, selectionArgs);
            break;
        case BOOK_ID:
            count = booksDB.update(DATABASE_TABLE, values,
                    _ID + " = " + uri.getPathSegments().get(1)
                            + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""),
                    selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        if (count == 1) {
            Cursor c = query(uri, new String[] { _ID }, selection, selectionArgs, null);
            long rowId = Long.valueOf(c.getString(c.getColumnIndex(_ID)));
            uri = ContentUris.withAppendedId(CONTENT_URI, rowId);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;

    }

i will update table some how like

getContentResolver().update(MyContentProvider.CONTENT_URI, values1, MyContentProvider._ID+"<?", new String[]{"3"}));

frankly saying, code has barely related to question, just trying to give you some context

Answer

Bruno Pinto picture Bruno Pinto · Oct 23, 2014

In your provider method, just return the uri with the id appended

@Override
public Uri insert(Uri uri, ContentValues values) {
    Log.i(TAG, "insert " + uri);
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    final int match = URI_MATCHER.match(uri);

    Uri returnUri;
    switch (match) {
        case MESSAGE: {
            long _id = db.insert(MessageContract.MessageEntry.TABLE_NAME, null, values);
            if (_id > 0)
                returnUri = ContentUris.withAppendedId(MessageContract.MessageEntry.CONTENT_URI, _id);
            else
                throw new android.database.SQLException("Failed to insert row into " + uri);
            break;
        }

        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
    }

    getContext().getContentResolver().notifyChange(returnUri, null);


    return returnUri;
}

And register your observer with true for descendents.

getContentResolver().registerContentObserver(MessageContract.MessageEntry.CONTENT_URI, true, mContentObserver);

To get the id from a Uri you can use ContentUris.parseId(uri)