littleK
littleK

Reputation: 20123

Android LoaderManager and CursorLoader Confusion

I am trying to convert my Android application to use the LoaderManager and CursorLoader. Basically, I have an SQLite database containing an ADDRESS column and a DISTANCE column, and I want to load the column values into my ListView rows.

Now, I have done a lot of research, and everything points to this tutorial: http://mobile.tutsplus.com/tutorials/android/android-sdk_content-providers/

It's a nice tutorial, but there are a couple of things that I still don't understand. Mainly, how do I construct the content URI that gets passed into 'new CursorLoader()'? I'm not using any external data such from the device Contacts, etc.

Please see my code below. I am confused as to how to generate the value for BASE_URI:

public class FavoritesFragment extends ListFragment implements
    LoaderManager.LoaderCallbacks<Cursor> {

SimpleCursorAdapter mAdapter;

static final String[] FAVORITES_SUMMARY_PROJECTION = new String[] {
        MyApplication.COLUMN_ID, MyApplication.COLUMN_ADDRESS,
        MyApplication.COLUMN_DISTANCE, };

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mAdapter = new SimpleCursorAdapter(getActivity(),
            R.layout.locations_list_row, null, new String[] {
                    MyApplication.COLUMN_ADDRESS,
                    MyApplication.COLUMN_DISTANCE }, new int[] {
                    R.id.address2, R.id.distance }, 0);
    setListAdapter(mAdapter);

    getLoaderManager().initLoader(0, null, this);
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    // Insert desired behavior here.
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    return new CursorLoader(getActivity(), ***BASE_URI***,
            FAVORITES_SUMMARY_PROJECTION, null, null, null);
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mAdapter.swapCursor(data);
}

public void onLoaderReset(Loader<Cursor> loader) {
    mAdapter.swapCursor(null);
}

}

Upvotes: 3

Views: 4953

Answers (1)

Sam Dozor
Sam Dozor

Reputation: 40724

BASE_URI should be a static Uri defined in your ContentProvider, it is used so that when you make a query/update/insert/whatever to the ContentProvider, a UriMatcher which is also defined in the ContentProvider can output an Integer allowing you to use a Switch statement (as in the example of the query() method in that tutorial) to setup the right query to the correct table in your database. You should define a different BASE_URI for each table in your database.

If you look at that tutorial they have defined a single Uri in the ContentProvider:

private static final String TUTORIALS_BASE_PATH = "tutorials";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
        + "/" + TUTORIALS_BASE_PATH);

In your ContentProvider, you should change the value of TUTORIALS_BASE_PATH from "tutorials" to whatever the name of your table is that contains the ADDRESS and DISTANCE columns that you mentioned. Your CursorLoader constructor code would look like this:

return new CursorLoader(getActivity(), YourContentProvider.CONTENT_URI,
            FAVORITES_SUMMARY_PROJECTION, null, null, null);

For completeness, you should change the variable names to be more descriptive, so rather than TUTORIALS_BASE_PATH and CONTENT_URI, you should change it to something like LOCATIONS_BASE_PATH and LOCATIONS_URI.

Upvotes: 7

Related Questions