Tuesday, May 17, 2011

ListPreference Using SQL Cursor

I wanted to have a ListPreference for my application that is filled with data contained in a SQLiteDatabase. Therefore, I wanted to have a cursor filling the mEntries and mEntryValues of the ListPreference class.

In order to do this, I extended the ListPreference class and simply added the following method to it. I named this class CursorListPreference.

public void setData(String inTableName, String inColumnName) {
    mySQLDataBase.open(); //Usually handled by a DB helper 
    
    CharSequence[] lEntries;
    CharSequence[] lEntryValues;
    
    Cursor lCursor = mySQLDataBase.query(
        inTableName, //Table to select from
        new String[]{"_id", inColumnName}, //Column to retreive
        null, null, null, null, 
        inColumnName); //Sorting
    if ((lCursor.getCount() == 0) || !lCursor.moveToFirst()) {
        lEntries = new CharSequence[]{};
        lEntryValues = new CharSequence[]{};
        Logger.i("No entry found for " + inColumnName + " in table " + inTableName);
    } else {
        lCursor.moveToFirst();
        lEntries = new CharSequence[lCursor.getCount()];
        lEntryValues = new CharSequence[lCursor.getCount()];
        int i = 0;
        do {
            lEntries[i] = lCursor.getString(lCursor.getColumnIndex(inColumnName));
            lEntryValues[i] = lCursor.getString(lCursor.getColumnIndex("_id"));
            ++i;
        } while (lCursor.moveToNext());
    }
    
    this.setEntries(lEntries);
    this.setEntryValues(lEntryValues);
    
    mySQLDataBase.close(); //Usually handled by a DB helper
}

Then, in my extension of PreferenceActivity, I could define the data that will be displayed in the list by providing the table name where to find the data and the column name to be displayed.
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        
    //Load the preferences from an XML resource
    addPreferencesFromResource(R.xml.preferences);
        
    PreferenceScreen preferenceScreen = getPreferenceScreen();
    CursorListPreference lCameraPref = (CursorListPreference) preferenceScreen.findPreference("camera");
    lCameraPref.setData("camera", "model");
}

public static long getDefaultCamera(Context context) {
    return Long.valueOf(
       PreferenceManager.getDefaultSharedPreferences(context).getString("camera_pref_id", "1"));
}

In this example, I have a table containing a list of cameras, and I want the user to set the default camera model to be used.

With this approach, I can easily retrieve the default object since the database entry id is stored as the preference value. Moreover, as this class extends ListPreference, this preference will behave and look like any other ListPreference. Even the XML attributes are defined as usual.

1 comment: