Android向记事本示例添加更多保存结果
Posted
技术标签:
【中文标题】Android向记事本示例添加更多保存结果【英文标题】:Android adding more save results to Notepad sample 【发布时间】:2011-07-18 14:48:30 【问题描述】:我试图通过示例操作 Google 已经编写的代码来学习 android 平台。我一直在编辑记事本示例,并在笔记本身中添加了一些新项目,现在正试图让它保存。它似乎没有问题,直到它尝试将值输入数据库以保存它似乎,但作为一个新手,我很难指出该位置。下面我决定从 NoteEditor.java 文件中复制我的代码:
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("");
希望我没有从文件中包含太多内容,我删除了顶部的导入和版权以节省更多空间,但不确定需要什么来正确分析问题并帮助更好地向我解释。
谢谢 迈克尔
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.
【问题讨论】:
DDMS 输出是什么样的? 已更新 DDMS 错误输出 【参考方案1】:DDMS 输出显示尝试保存时出错:
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
显然您的数据库中没有 CHOICE 列,或者您有一个但已将其删除。
此错误出现在您的 com.example.android.notepad.NotePadProvider
类的 update
方法中。您没有发布该课程的源代码,但应该很容易发现问题。
【讨论】:
感谢您的回答。我不知道我在这里做什么。我继续在我的 OP 中添加了代码文件。我已经搞砸了 C#,所以你会认为 java 会很容易,但我认为 SQLLite 也可能是我的失败之处。我根本没有搞砸这个,所以这对我来说都是陌生的......【参考方案2】:好的,感谢您发布。粗略(双关语)一目了然告诉我数据库没有名为“CHOICE”的列。您的数据库创建代码一目了然。
可能旧版本的数据库挂在您的系统上。擦除您的用户数据以清除所有旧数据库。
【讨论】:
以上是关于Android向记事本示例添加更多保存结果的主要内容,如果未能解决你的问题,请参考以下文章