I’m not very experienced with Android and Java in general, so my terms may be wrong. Sorry for that.
Any way. I have a ListActivity which gets the data from a LoaderManager. LoaderManager uses ContentProvider https://github.com/jakenjarvis/Android-OrmLiteContentProvider.
Everything is working well when the data is fetched using the contentUri (net.mydomain.app.listitems), which is defined pretty much the same way as in the example setup. But I needed data from a join query and added a URI (net.mydomain.app.listitems/items_joined) for that query. The uri is defined in the Contract class and named as itemsJoinedUri. When using this URI the list in the view is not updated when new data is inserted to the table.
In my ContentProvider class’s onQuery method I do a custom query if the “pattern code” matches to the itemsJoinedUri. Other vice I pass the work to the super method.
public class DataProvider extends OrmLiteSimpleContentProvider<DatabaseHelper> {
@Override
protected Class<DatabaseHelper> getHelperClass() {
return DatabaseHelper.class;
}
@Override
public boolean onCreate() {
Controller = new MatcherController()
.add(ListItem.class, SubType.Directory, "", Contract.ListItem.CONTENT_URI_PATTERN_MANY)
.add(ListItem.class, SubType.Item, "#", Contract.ListItem.CONTENT_URI_PATTERN_ONE)
.add(ListItem.class, SubType.Directory, "items_joined", Contract.ListItem.CONTENT_URI_PATTERN_WITH_ITEMS_JOINED)
.initialize();
return true;
}
@Override
public Cursor onQuery(DatabaseHelper helper, MatcherPattern target, QueryParameters parameter) {
Cursor result = null;
//SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
switch(target.getPatternCode()) {
case 310:
String MY_QUERY = "SELECT items.name as name, listitems._id as _id FROM listitems INNER JOIN items ON items._id = listitems.item_id WHERE list_id = ?";
SQLiteDatabase db = helper.getReadableDatabase();
result = db.rawQuery(MY_QUERY, parameter.getSelectionArgs());
break;
default:
result = super.onQuery(helper, target, parameter);
break;
}
return result;
}
}
My Contract implementation for the relevant part:
public class Contract {
public static final String DATABASE_NAME = "mydatabase.db";
public static final int DATABASE_VERSION = 1;
public static final String AUTHORITY = "net.mydomain.app";
.
.
.
public static class ListItem implements BaseColumns {
public static final String TABLENAME = "listitems";
public static final String CONTENT_URI_PATH = TABLENAME;
public static final String MIMETYPE_TYPE = TABLENAME;
public static final String MIMETYPE_NAME = AUTHORITY + ".provider";
// field info
public static final String ITEM = "item_id";
public static final String LIST = "list_id";
public static final String QUANTITY = "quantity";
// content uri pattern code
public static final int CONTENT_URI_PATTERN_MANY = 300;
public static final int CONTENT_URI_PATTERN_ONE = 301;
public static final int CONTENT_URI_PATTERN_WITH_ITEMS_JOINED = 310;
// Refer to activity.
public static final Uri contentUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.appendPath(CONTENT_URI_PATH)
.build();
public static final Uri itemsJoinedUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.appendPath(CONTENT_URI_PATH)
.appendPath("items_joined")
.build();
}
}
The ListActivity’s onCreateLoader methods are here. The one which I would like to use but which is not updating the list correctly is commented out.
// @Override
// public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
// String[] selectArgs = { "" + list_id };
// Uri baseUri = Contract.ListItem.itemsJoinedUri;
// return new CursorLoader(this, baseUri, null, null, selectArgs, null);
// }
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
String select = "( " + Contract.ListItem.LIST + " = 2 )";
Uri baseUri = Contract.ListItem.contentUri;
String[] projection = new String[] {
Contract.ListItem._ID,
Contract.ListItem.LIST
};
return new CursorLoader(this, baseUri, projection, select, null, null);
}
New items to the list are inserted in a different Activity using a code getContentResolver().insert(Contract.ListItem.contentUri, values);. That Activity is one step deeper in the hierarchy than the ListActivity so I can get back to the ListActivity with the back button, and that is when I see that the list has not updated.
So the data is inserted using the contentUri but read using my own itemsJoinedUri. Could that be the issue here?
EDIT
I added a simple clicklistener to delete a row from the list. That uses the contentUri and the list is automatically updated after the delete. So I guess the issue for list not being updated when moving back to the list from another Activity might relate to faulty implementation of the life cycle of the ListActivity.
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String[] args = { "" + id};
getContentResolver().delete(Contract.ListItem.contentUri, "_id = ?", args);
}
The issue was in the life cycle management. I didn’t have proper onRestart() implementation. After adding this everything works.