tyczj
tyczj

Reputation: 73753

Loader not getting callbacks to update ListFragment

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 theListFragment` 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

Answers (1)

superfell
superfell

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

Related Questions