Reputation: 73753
I have an activity that goes and pulls all the users calendar events from the google calendar, the get inserted into the database fine but the Loader for the
ListFragment` of the activity never gets the callbacks to refresh the list when there is a change. I have to back out of the activity then come back in for the loader to load everything up correctly.
I have done loaders before and never had this problem, I basically copied the loader from another of my projects that works correctly so I dont under stand why its not getting the callbacks when the content changes?
this is my insert method into the database
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(EVENTS_TABLE,null, values);
Uri _uri = null;
if(rowID > 0){
_uri = ContentUris.withAppendedId(CONTENT_ID_URI_BASE,rowID);
getContext().getContentResolver().notifyChange(_uri,null);
}else{
throw new SQLException("Failed to insert row into " + uri);
}
return _uri;
}
as you can see I am calling notifyChange
so the adapter updates but it does not.
this is my ListFragment
@Override
public void onActivityCreated(Bundle state){
super.onActivityCreated(state);
lv = getListView();
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
View v = getView();
v.setClickable(true);
setEmptyText("No Events");
populate();
}
public void populate(){
mAdapter = new CalendarRowAdapter(getActivity(), R.layout.calendar_view, null,
new String[] {CalendarProvider.EVENT,CalendarProvider.LOCATION,CalendarProvider.DESCRIPTION,CalendarProvider.START},
new int[] {R.id.calendarEntryText,R.id.locationEntryText,R.id.descEntryText,R.id.dateEntryText},0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0,null,this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
CalendarProvider.CONTENT_URI,new String[] {CalendarProvider.ID,CalendarProvider.EVENT,
CalendarProvider.LOCATION,CalendarProvider.DESCRIPTION,CalendarProvider.START}
,null,null,CalendarProvider.START + " COLLATE LOCALIZED ASC");
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
mAdapter.swapCursor(arg1);
if(isResumed()){
setListShown(true);
}else{
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
like I said, everything is going into the database correctly, just the loader is not getting the callbacks to refresh the list.
the calendar events are put into the database from an AsyncTask
but I dont think thats the problem
The logcat shows no errors either
EDIT
my query method
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
sqlBuilder.setTables(EVENTS_TABLE);
if(uriMatcher.match(uri) == 1){
sqlBuilder.setProjectionMap(mMap);
}else if(uriMatcher.match(uri) == 2){
sqlBuilder.setProjectionMap(mMap);
sqlBuilder.appendWhere(ID + "=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,new String[] {uri.getLastPathSegment()});
}
if(sortOrder == null || sortOrder == "")
sortOrder = START + " COLLATE LOCALIZED ASC";
Cursor c = sqlBuilder.query(db, projection, selection, selectionArgs,null,null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
Upvotes: 2
Views: 1284
Reputation: 19040
in your insert method you call notifyChange
with the URI for that specific row that was inserted,but on the query side, the URI is a different URI that represents the entire data set. notifyChange
on /foo/bar/1
won't notify listeners listening for /foo/bar
. So in your insert()
method you need to call notifyChange
with the URI for the dataset, rather than the particular row.
Upvotes: 4