Search code examples
androiddatabasesavenotepad

Android adding more save results to Notepad sample


Im trying to learn the android platform by manipulating code already written by Google through the samples. I have been editing the Notepad sample, and have added a few new items to the note itself, and am now trying to allow it to save. It doesnt seem to have a problem until it tries to enter the values into the db for saving it seems, but being a newb, Im having a hard time pin pointing the location. Below I have decided to copy my code from the NoteEditor.java file:

public class NoteEditor extends Activity {
private static final String TAG = "NoteEditor";

/**
 * Standard projection for the interesting columns of a normal note.
 */
private static final String[] PROJECTION = new String[] {
    NoteColumns._ID, // 0
    NoteColumns.NOTE, // 1
    NoteColumns.TITLE, // 2
    //NoteColumns.DATE, //3
    //NoteColumns.TIME, //4
    //NoteColumns.CHOICE, //5
};
/** The index of the note column */
private static final int COLUMN_INDEX_NOTE = 1;
/** The index of the title column */
private static final int COLUMN_INDEX_TITLE = 2;

// This is our state data that is stored when freezing.
private static final String ORIGINAL_CONTENT = "origContent";

// The different distinct states the activity can be run in.
private static final int STATE_EDIT = 0;
private static final int STATE_INSERT = 1;

private int mState;
private Uri mUri;
private Cursor mCursor;
private DatePicker mPicker;
private TimePicker mTime;
private Spinner mChoice;
private EditText mText;
private String mOriginalContent;

/**
 * A custom EditText that draws lines between each line of text that is displayed.
 */
public static class LinedEditText extends EditText {
    private Rect mRect;
    private Paint mPaint;

    // we need this constructor for LayoutInflater
    public LinedEditText(Context context, AttributeSet attrs) {
        super(context, attrs);

        mRect = new Rect();
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(0x800000FF);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int count = getLineCount();
        Rect r = mRect;
        Paint paint = mPaint;

        for (int i = 0; i < count; i++) {
            int baseline = getLineBounds(i, r);

            canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
        }

        super.onDraw(canvas);
    }
}

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

    final Intent intent = getIntent();




    // Do some setup based on the action being performed.
    final String action = intent.getAction();
    if (Intent.ACTION_EDIT.equals(action)) {
        // Requested to edit: set that state, and the data being edited.
        mState = STATE_EDIT;
        mUri = intent.getData();
    } else if (Intent.ACTION_INSERT.equals(action)) {
        // Requested to insert: set that state, and create a new entry
        // in the container.
        mState = STATE_INSERT;
        mUri = getContentResolver().insert(intent.getData(), null);

        // If we were unable to create a new note, then just finish
        // this activity.  A RESULT_CANCELED will be sent back to the
        // original activity if they requested a result.
        if (mUri == null) {
            Log.e(TAG, "Failed to insert new project into " + getIntent().getData());
            finish();
            return;
        }

        // The new entry was created, so assume all will end well and
        // set the result to be returned.
        setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));

    } else {
        // Whoops, unknown action!  Bail.
        Log.e(TAG, "Unknown action, exiting");
        finish();
        return;
    }

    // Set the layout for this activity.  You can find it in res/layout/note_editor.xml
    setContentView(R.layout.note_editor);

    Spinner spinner = (Spinner) findViewById(R.id.spinner1);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.spinnerss, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    // The text view for our note, identified by its ID in the XML file.
    mText = (EditText) findViewById(R.id.note);
    mTime = (TimePicker) findViewById(R.id.timePicker1);
    mPicker = (DatePicker) findViewById(R.id.datePicker1);
    mChoice = (Spinner) findViewById(R.id.spinner1);

    // Get the note!
    mCursor = managedQuery(mUri, PROJECTION, null, null, null);

    // If an instance of this activity had previously stopped, we can
    // get the original text it started with.
    if (savedInstanceState != null) {
        mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
    }
}

@Override
protected void onResume() {
    super.onResume();
    // If we didn't have any trouble retrieving the data, it is now
    // time to get at the stuff.
    if (mCursor != null) {
        // Requery in case something changed while paused (such as the title)
        mCursor.requery();
        // Make sure we are at the one and only row in the cursor.
        mCursor.moveToFirst();

        // Modify our overall title depending on the mode we are running in.
        if (mState == STATE_EDIT) {
            // Set the title of the Activity to include the note title
            String title = mCursor.getString(COLUMN_INDEX_TITLE);
            Resources res = getResources();
            String text = String.format(res.getString(R.string.title_edit), title);
            setTitle(text);
        } else if (mState == STATE_INSERT) {
            setTitle(getText(R.string.title_create));
        }

        // This is a little tricky: we may be resumed after previously being
        // paused/stopped.  We want to put the new text in the text view,
        // but leave the user where they were (retain the cursor position
        // etc).  This version of setText does that for us.
        String note = mCursor.getString(COLUMN_INDEX_NOTE);
        mText.setTextKeepState(note);

        // If we hadn't previously retrieved the original text, do so
        // now.  This allows the user to revert their changes.
        if (mOriginalContent == null) {
            mOriginalContent = note;
        }

    } else {
        setTitle(getText(R.string.error_title));
        mText.setText(getText(R.string.error_message));
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save away the original text, so we still have it if the activity
    // needs to be killed while paused.
    outState.putString(ORIGINAL_CONTENT, mOriginalContent);
}

@Override
protected void onPause() {
    super.onPause();
    // The user is going somewhere, so make sure changes are saved

    String text = mText.getText().toString();
    int length = text.length();

    // If this activity is finished, and there is no text, then we
    // simply delete the note entry.
    // Note that we do this both for editing and inserting...  it
    // would be reasonable to only do it when inserting.
    if (isFinishing() && (length == 0) && mCursor != null) {
        setResult(RESULT_CANCELED);
        deleteNote();
    } else {
        saveNote();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate menu from XML resource
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.editor_options_menu, menu);

    // Append to the
    // menu items for any other activities that can do stuff with it
    // as well.  This does a query on the system for any activities that
    // implement the ALTERNATIVE_ACTION for our data, adding a menu item
    // for each one that is found.
    Intent intent = new Intent(null, getIntent().getData());
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
    menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
            new ComponentName(this, NoteEditor.class), null, intent, 0, null);

    return super.onCreateOptionsMenu(menu);
}



@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (mState == STATE_EDIT) {
        menu.setGroupVisible(R.id.menu_group_edit, true);
        menu.setGroupVisible(R.id.menu_group_insert, false);

        // Check if note has changed and enable/disable the revert option
        String savedNote = mCursor.getString(COLUMN_INDEX_NOTE);
        String currentNote = mText.getText().toString();
        if (savedNote.equals(currentNote)) {
            menu.findItem(R.id.menu_revert).setEnabled(false);
        } else {
            menu.findItem(R.id.menu_revert).setEnabled(true);
        }
    } else {
        menu.setGroupVisible(R.id.menu_group_edit, false);
        menu.setGroupVisible(R.id.menu_group_insert, true);
    }
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle all of the possible menu actions.
    switch (item.getItemId()) {
    case R.id.menu_save:
        saveNote();
        finish();
        break;
    case R.id.menu_delete:
        deleteNote();
        finish();
        break;
    case R.id.menu_revert:
    case R.id.menu_discard:
        cancelNote();
        break;
    }
    return super.onOptionsItemSelected(item);

}

private final void saveNote() {
    // Make sure their current
    // changes are safely saved away in the provider.  We don't need
    // to do this if only editing.
    if (mCursor != null) {
        // Get out updates into the provider.
        ContentValues values = new ContentValues();

        // Bump the modification time to now.
        values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());

        String text = mText.getText().toString();
        //String date = mPicker.toString();
        //String time = mTime.toString();
        String choice = mChoice.toString();
        int length = text.length();
        // If we are creating a new note, then we want to also create
        // an initial title for it.
        if (mState == STATE_INSERT) {
            if (length == 0) {
                Toast.makeText(this, R.string.nothing_to_save, Toast.LENGTH_SHORT).show();
                return;
            }
            String title = text.substring(0, Math.min(30, length));
            if (length > 30) {
                int lastSpace = title.lastIndexOf(' ');
                if (lastSpace > 0) {
                    title = title.substring(0, lastSpace);
                }
            }
            values.put(NoteColumns.TITLE, title);
        }

        // Write our text back into the provider.
        values.put(NoteColumns.NOTE, text);
        //values.put(NoteColumns.DATE, date);
        //values.put(NoteColumns.TIME, time);
        //values.put(NoteColumns.CHOICE, choice);

        // Commit all of our changes to persistent storage. When the update completes
        // the content provider will notify the cursor of the change, which will
        // cause the UI to be updated.
        try {
            getContentResolver().update(mUri, values, null, null);
        } catch (NullPointerException e) {
            Log.e(TAG, e.getMessage());
        }

    }
}

/**
 * Take care of canceling work on a note.  Deletes the note if we
 * had created it, otherwise reverts to the original text.
 */
private final void cancelNote() {
    if (mCursor != null) {
        if (mState == STATE_EDIT) {
            // Put the original note text back into the database
            mCursor.close();
            mCursor = null;
            ContentValues values = new ContentValues();
            values.put(NoteColumns.NOTE, mOriginalContent);
            getContentResolver().update(mUri, values, null, null);
        } else if (mState == STATE_INSERT) {
            // We inserted an empty note, make sure to delete it
            deleteNote();
        }
    }
    setResult(RESULT_CANCELED);
    finish();
}

/**
 * Take care of deleting a note.  Simply deletes the entry.
 */
private final void deleteNote() {
    if (mCursor != null) {
        mCursor.close();
        mCursor = null;
        getContentResolver().delete(mUri, null, null);
        mText.setText("");
    }
}
}

Hopefully I didnt include too much from the file, I knocked out the imports and copyrights at the top to save more room, but wasnt sure what was needed to properly analyze the issue and help explain it better to me.

Thanks Michael

DDMS:

07-18 10:27:49.757: ERROR/Database(25136): Error updating   choice=android.widget.Spinner@40551ea0 note=Blah burger
07-18 10:27:49.757: ERROR/Database(25136): T
07-18 10:27:49.757: ERROR/Database(25136):  modified=1311002869768 using UPDATE notes SET choice=?, note=?, modified=? WHERE _id=1
07-18 10:27:49.817: ERROR/AndroidRuntime(25136): FATAL EXCEPTION: main
07-18 10:27:49.817: ERROR/AndroidRuntime(25136): java.lang.RuntimeException: Unable to   pause activity {com.example.android.notepad/com.example.android.notepad.NoteEditor}:   android.database.sqlite.SQLiteException: no such column: choice: , while compiling: UPDATE   notes SET choice=?, note=?, modified=? WHERE _id=1
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2731)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2678)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2651)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.ActivityThread.access$1700(ActivityThread.java:132)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1049)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.os.Looper.loop(Looper.java:143)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.ActivityThread.main(ActivityThread.java:4263)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at java.lang.reflect.Method.invokeNative(Native Method)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at java.lang.reflect.Method.invoke(Method.java:507)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at dalvik.system.NativeStart.main(Native Method)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136): Caused by: android.database.sqlite.SQLiteException: no such column: choice: , while compiling: UPDATE notes SET choice=?, note=?, modified=? WHERE _id=1
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:41)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1231)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1813)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1763)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at com.example.android.notepad.NotePadProvider.update(NotePadProvider.java:235)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.content.ContentProvider$Transport.update(ContentProvider.java:240)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.content.ContentResolver.update(ContentResolver.java:726)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at com.example.android.notepad.NoteEditor.saveNote(NoteEditor.java:357)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at com.example.android.notepad.NoteEditor.onPause(NoteEditor.java:247)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at android.app.Activity.performPause(Activity.java:3988)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at   android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1313)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     at       android.app.ActivityThread.performPauseActivity(ActivityThread.java:2708)
07-18 10:27:49.817: ERROR/AndroidRuntime(25136):     ... 12 more

NotepadProvider.java:

public class NotePadProvider extends ContentProvider {

private static final String TAG = "NotePadProvider";

private static final String DATABASE_NAME = "notepad.db";
private static final int DATABASE_VERSION = 2;
private static final String NOTES_TABLE_NAME = "notes";

private static HashMap<String, String> sNotesProjectionMap;
private static HashMap<String, String> sLiveFolderProjectionMap;

private static final int NOTES = 1;
private static final int NOTE_ID = 2;
private static final int LIVE_FOLDER_NOTES = 3;

private static final UriMatcher sUriMatcher;

/**
 * This class helps open, create, and upgrade the database file.
 */
private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
                + NoteColumns._ID + " INTEGER PRIMARY KEY,"
                + NoteColumns.TITLE + " TEXT,"
                + NoteColumns.NOTE + " TEXT,"
                + NoteColumns.TIME + " TEXT,"
                + NoteColumns.DATE + " TEXT,"
                + NoteColumns.CHOICE + " TEXT,"
                + NoteColumns.CREATED_DATE + " INTEGER,"
                + NoteColumns.MODIFIED_DATE + " INTEGER"
                + ");");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS notes");
        onCreate(db);
    }
}

private DatabaseHelper mOpenHelper;

@Override
public boolean onCreate() {
    mOpenHelper = new DatabaseHelper(getContext());
    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
        String sortOrder) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    qb.setTables(NOTES_TABLE_NAME);

    switch (sUriMatcher.match(uri)) {
    case NOTES:
        qb.setProjectionMap(sNotesProjectionMap);
        break;

    case NOTE_ID:
        qb.setProjectionMap(sNotesProjectionMap);
        qb.appendWhere(NoteColumns._ID + "=" + uri.getPathSegments().get(1));
        break;

    case LIVE_FOLDER_NOTES:
        qb.setProjectionMap(sLiveFolderProjectionMap);
        break;

    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    // If no sort order is specified use the default
    String orderBy;
    if (TextUtils.isEmpty(sortOrder)) {
        orderBy = NoteColumns.DEFAULT_SORT_ORDER;
    } else {
        orderBy = sortOrder;
    }

    // Get the database and run the query
    SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);

    // Tell the cursor what uri to watch, so it knows when its source data changes
    c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
}

@Override
public String getType(Uri uri) {
    switch (sUriMatcher.match(uri)) {
    case NOTES:
    case LIVE_FOLDER_NOTES:
        return NoteColumns.CONTENT_TYPE;

    case NOTE_ID:
        return NoteColumns.CONTENT_ITEM_TYPE;

    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
}

@Override
public Uri insert(Uri uri, ContentValues initialValues) {
    // Validate the requested uri
    if (sUriMatcher.match(uri) != NOTES) {
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    ContentValues values;
    if (initialValues != null) {
        values = new ContentValues(initialValues);
    } else {
        values = new ContentValues();
    }

    Long now = Long.valueOf(System.currentTimeMillis());

    // Make sure that the fields are all set
    if (values.containsKey(NoteColumns.CREATED_DATE) == false) {
        values.put(NoteColumns.CREATED_DATE, now);
    }

    if (values.containsKey(NoteColumns.MODIFIED_DATE) == false) {
        values.put(NoteColumns.MODIFIED_DATE, now);
    }

    if (values.containsKey(NoteColumns.TITLE) == false) {
        Resources r = Resources.getSystem();
        values.put(NoteColumns.TITLE, r.getString(android.R.string.untitled));
    }

    if (values.containsKey(NoteColumns.NOTE) == false) {
        values.put(NoteColumns.NOTE, "");
    }

    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    long rowId = db.insert(NOTES_TABLE_NAME, NoteColumns.NOTE, values);
    if (rowId > 0) {
        Uri noteUri = ContentUris.withAppendedId(NoteColumns.CONTENT_URI, rowId);
        getContext().getContentResolver().notifyChange(noteUri, null);
        return noteUri;
    }

    throw new SQLException("Failed to insert row into " + uri);
}

@Override
public int delete(Uri uri, String where, String[] whereArgs) {
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;
    switch (sUriMatcher.match(uri)) {
    case NOTES:
        count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
        break;

    case NOTE_ID:
        String noteId = uri.getPathSegments().get(1);
        count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId
                + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
        break;

    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    getContext().getContentResolver().notifyChange(uri, null);
    return count;
}

@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;
    switch (sUriMatcher.match(uri)) {
    case NOTES:
        count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);
        break;

    case NOTE_ID:
        String noteId = uri.getPathSegments().get(1);
        count = db.update(NOTES_TABLE_NAME, values, NoteColumns._ID + "=" + noteId
                + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
        break;

    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    getContext().getContentResolver().notifyChange(uri, null);
    return count;
}

static {
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
    sUriMatcher.addURI(NotePad.AUTHORITY, "choice", NOTES);
    sUriMatcher.addURI(NotePad.AUTHORITY, "date", NOTES);
    sUriMatcher.addURI(NotePad.AUTHORITY, "time", NOTES);
    sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
    sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);

    sNotesProjectionMap = new HashMap<String, String>();
    sNotesProjectionMap.put(NoteColumns._ID, NoteColumns._ID);
    sNotesProjectionMap.put(NoteColumns.TITLE, NoteColumns.TITLE);
    sNotesProjectionMap.put(NoteColumns.NOTE, NoteColumns.NOTE);
    sNotesProjectionMap.put(NoteColumns.CHOICE, NoteColumns.CHOICE);
    sNotesProjectionMap.put(NoteColumns.TIME, NoteColumns.TIME);
    sNotesProjectionMap.put(NoteColumns.DATE, NoteColumns.DATE);
    sNotesProjectionMap.put(NoteColumns.CREATED_DATE, NoteColumns.CREATED_DATE);
    sNotesProjectionMap.put(NoteColumns.MODIFIED_DATE, NoteColumns.MODIFIED_DATE);

    // Support for Live Folders.
    sLiveFolderProjectionMap = new HashMap<String, String>();
    sLiveFolderProjectionMap.put(LiveFolders._ID, NoteColumns._ID + " AS " +
            LiveFolders._ID);
    sLiveFolderProjectionMap.put(LiveFolders.NAME, NoteColumns.TITLE + " AS " +
            LiveFolders.NAME);
    // Add more columns here for more robust Live Folders.
}
}

Solution

  • OK thanks for posting that. A cursory (pun intended) glance tells me that the database does not have a column called "CHOICE". Your database creation code looks OK at a glance.

    Maybe an old version of the database is hanging out on your system. Wipe your user data to clear out any old databases.