2

这是代码:

TodoTable.java:

public class TodoTable {

// Database table
public static final String TABLE_TODO = "todo";
public static final String COLUMN_ID_U = "_id";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_SUMMARY = "summary";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_SATZE = "satze";

// Database creation SQL statement
private static final String DATABASE_CREATE = "create table " 
        + TABLE_TODO
        + "(" 
        + COLUMN_ID_U + " integer primary key autoincrement, " 
        + COLUMN_CATEGORY + " text not null, " 
        + COLUMN_SUMMARY + " text not null, " 
        + COLUMN_DESCRIPTION + " text not null, " 
        + COLUMN_SATZE + " text not null" 
        + ");";

public static void onCreate(SQLiteDatabase database) {
    database.execSQL(DATABASE_CREATE);
}

public static void onUpgrade(SQLiteDatabase database, int oldVersion,
        int newVersion) {
    Log.w(TodoTable.class.getName(), "Upgrading database from version "
            + oldVersion + " to " + newVersion
            + ", which will destroy all old data");
    database.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO);
    onCreate(database);
}}

TodoDetailAktivity.java:

public class TodoDetailActivity extends Activity {
private Spinner mCategory;
private EditText mTitleText;
private EditText mBodyText;
private EditText mSatzText;
private EditText mPauseText;
private EditText mWDHText;
private EditText mGewichtText;

private Uri todoUri;

@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.todo_edit);

    mCategory = (Spinner) findViewById(R.id.category);
    mTitleText = (EditText) findViewById(R.id.todo_edit_summary);
    mBodyText = (EditText) findViewById(R.id.todo_edit_description);
    mSatzText = (EditText) findViewById(R.id.editTextsatz);
    Button confirmButton = (Button) findViewById(R.id.todo_edit_button);

    Bundle extras = getIntent().getExtras();

    // Check from the saved Instance
    todoUri = (bundle == null) ? null : (Uri) bundle
            .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);

    // Or passed from the other activity
    if (extras != null) {
        todoUri = extras
                .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);

        fillData(todoUri);
    }

    confirmButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            if (TextUtils.isEmpty(mTitleText.getText().toString())) {
                makeToast();
            } else {
                setResult(RESULT_OK);
                finish();
            }
        }

    });
}

private void fillData(Uri uri) {
    String[] projection = { TodoTable.COLUMN_SUMMARY,
            TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
    Cursor cursor = getContentResolver().query(uri, projection, null, null,
            null);
    if (cursor != null) {
        cursor.moveToFirst();
        String category = cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));

        for (int i = 0; i < mCategory.getCount(); i++) {

            String s = (String) mCategory.getItemAtPosition(i);
            if (s.equalsIgnoreCase(category)) {
                mCategory.setSelection(i);
            }
        } 

        mTitleText.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
        mBodyText.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
        mSatzText.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_SATZE)));

        // Always close the cursor
        cursor.close();
    }
}

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    saveState();
    outState.putParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
}

@Override
protected void onPause() {
    super.onPause();
    saveState();
}

private void saveState() {
    String category = (String) mCategory.getSelectedItem();
    String summary = mTitleText.getText().toString();
    String description = mBodyText.getText().toString();
    String satze = mSatzText.getText().toString();

    // Only save if either summary or description
    // is available

    if (description.length() == 0 && summary.length() == 0 && satze.length() == 0) {
        return;
    }

    ContentValues values = new ContentValues();
    values.put(TodoTable.COLUMN_CATEGORY, category);
    values.put(TodoTable.COLUMN_SUMMARY, summary);
    values.put(TodoTable.COLUMN_DESCRIPTION, description);
    values.put(TodoTable.COLUMN_SATZE, satze);

    if (todoUri == null) {
        // New todo
        todoUri = getContentResolver().insert(MyTodoContentProvider.CONTENT_URI, values);
    } else {
        // Update todo
        getContentResolver().update(todoUri, values, null, null);
    }
}

private void makeToast() {
    Toast.makeText(TodoDetailActivity.this, "Please maintain a summary",
            Toast.LENGTH_LONG).show();
}}

TodosOverviewAktivity.java:

/*
 * TodosOverviewActivity displays the existing todo items
 * in a list
 * 
 * You can create new ones via the ActionBar entry "Insert"
 * You can delete existing ones via a long press on the item
 */

@TargetApi(11)
public class TodosOverviewActivity extends ListActivity implements
    LoaderManager.LoaderCallbacks<Cursor> {
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1;
// private Cursor cursor;
private SimpleCursorAdapter adapter;


/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.todo_list);
    this.getListView().setDividerHeight(1);
    fillData();
    registerForContextMenu(getListView());
}

// Create the menu based on the XML defintion
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.listmenu, menu);
    return true;
}

// Reaction to the menu selection
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.insert:
        createTodo();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case DELETE_ID:
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
                .getMenuInfo();
        Uri uri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/"
                + info.id);
        getContentResolver().delete(uri, null, null);
        fillData();
        return true;
    }
    return super.onContextItemSelected(item);
}

private void createTodo() {
    Intent i = new Intent(this, TodoDetailActivity.class);
    startActivityForResult(i, ACTIVITY_CREATE);
}

// Opens the second activity if an entry is clicked
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    Intent i = new Intent(this, TodoDetailActivity.class);
    Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
    i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);

    // Activity returns an result if called with startActivityForResult
    startActivityForResult(i, ACTIVITY_EDIT);
}

// Called with the result of the other activity
// requestCode was the origin request code send to the activity
// resultCode is the return code, 0 is everything is ok
// intend can be used to get data
@Override
protected void onActivityResult(int requestCode, int resultCode,
        Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
}

private void fillData() {

    // Fields from the database (projection)
    // Must include the _id column for the adapter to work
    String[] from = new String[] { TodoTable.COLUMN_SUMMARY };
    // Fields on the UI to which we map
    int[] to = new int[] { R.id.label };

    getLoaderManager().initLoader(0, null, this);
    adapter = new SimpleCursorAdapter(this, R.layout.todo_row, null, from,
            to, 0);

    setListAdapter(adapter);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}

// Creates a new loader after the initLoader () call

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String[] projection = { TodoTable.COLUMN_ID_U, TodoTable.COLUMN_SUMMARY };
    CursorLoader cursorLoader = new CursorLoader(this,
            MyTodoContentProvider.CONTENT_URI, projection, null, null, null);
    return cursorLoader;
}


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


@Override
public void onLoaderReset(Loader<Cursor> loader) {
    // data is not available anymore, delete reference
    adapter.swapCursor(null);
}}

MyTodoContentProvider.java:

public class MyTodoContentProvider extends ContentProvider {

// database
private TodoDatabaseHelper database;

// Used for the UriMacher
private static final int TODOS = 10;
private static final int TODO_ID = 20;

private static final String AUTHORITY = "de.vogella.android.todos.contentprovider";

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

public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
        + "/todos";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
        + "/todo";

private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
    sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS);
    sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID);
}

@Override
public boolean onCreate() {
    database = new TodoDatabaseHelper(getContext());
    return false;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {

    // Uisng SQLiteQueryBuilder instead of query() method
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

    // Check if the caller has requested a column which does not exists
    checkColumns(projection);

    // Set the table
    queryBuilder.setTables(TodoTable.TABLE_TODO);

    int uriType = sURIMatcher.match(uri);
    switch (uriType) {
    case TODOS:
        break;
    case TODO_ID:
        // Adding the ID to the original query
        queryBuilder.appendWhere(TodoTable.COLUMN_ID_U + "="
                + uri.getLastPathSegment());
        break;
    default:
        throw new IllegalArgumentException("Unknown URI: " + uri);
    }

    SQLiteDatabase db = database.getWritableDatabase();
    Cursor cursor = queryBuilder.query(db, projection, selection,
            selectionArgs, null, null, sortOrder);
    // Make sure that potential listeners are getting notified
    cursor.setNotificationUri(getContext().getContentResolver(), uri);

    return cursor;
}

@Override
public String getType(Uri uri) {
    return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    int uriType = sURIMatcher.match(uri);
    SQLiteDatabase sqlDB = database.getWritableDatabase();
    int rowsDeleted = 0;
    long id = 0;
    switch (uriType) {
    case TODOS:
        id = sqlDB.insert(TodoTable.TABLE_TODO, null, values);
        break;
    default:
        throw new IllegalArgumentException("Unknown URI: " + uri);
    }
    getContext().getContentResolver().notifyChange(uri, null);
    return Uri.parse(BASE_PATH + "/" + id);
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    int uriType = sURIMatcher.match(uri);
    SQLiteDatabase sqlDB = database.getWritableDatabase();
    int rowsDeleted = 0;
    switch (uriType) {
    case TODOS:
        rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO, selection,
                selectionArgs);
        break;
    case TODO_ID:
        String id = uri.getLastPathSegment();
        if (TextUtils.isEmpty(selection)) {
            rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,
                    TodoTable.COLUMN_ID_U + "=" + id, 
                    null);
        } else {
            rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,
                    TodoTable.COLUMN_ID_U + "=" + id 
                    + " and " + selection,
                    selectionArgs);
        }
        break;
    default:
        throw new IllegalArgumentException("Unknown URI: " + uri);
    }
    getContext().getContentResolver().notifyChange(uri, null);
    return rowsDeleted;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
        String[] selectionArgs) {

    int uriType = sURIMatcher.match(uri);
    SQLiteDatabase sqlDB = database.getWritableDatabase();
    int rowsUpdated = 0;
    switch (uriType) {
    case TODOS:
        rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO, 
                values, 
                selection,
                selectionArgs);
        break;
    case TODO_ID:
        String id = uri.getLastPathSegment();
        if (TextUtils.isEmpty(selection)) {
            rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO, 
                    values,
                    TodoTable.COLUMN_ID_U + "=" + id, 
                    null);
        } else {
            rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO, 
                    values,
                    TodoTable.COLUMN_ID_U + "=" + id 
                    + " and " 
                    + selection,
                    selectionArgs);
        }
        break;
    default:
        throw new IllegalArgumentException("Unknown URI: " + uri);
    }
    getContext().getContentResolver().notifyChange(uri, null);
    return rowsUpdated;
}

private void checkColumns(String[] projection) {
    String[] available = { TodoTable.COLUMN_CATEGORY,
            TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_SATZE, TodoTable.COLUMN_ID_U };
    if (projection != null) {
        HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
        HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
        // Check if all columns which are requested are available
        if (!availableColumns.containsAll(requestedColumns)) {
            throw new IllegalArgumentException("Unknown columns in projection");
        }
    }
}

} 

TodoDatabaseHelper.java:

public class TodoDatabaseHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "todotable.db";
private static final int DATABASE_VERSION = 1;

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

// Method is called during creation of the database
@Override
public void onCreate(SQLiteDatabase database) {
    TodoTable.onCreate(database);
}

// Method is called during an upgrade of the database,
// e.g. if you increase the database version
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
        int newVersion) {
    TodoTable.onUpgrade(database, oldVersion, newVersion);
}
} 

我复制的大部分代码:http ://www.vogella.com/articles/AndroidSQLite/article.html#todo

但我收到错误消息(LogCat):

java.lang.RuntimeException:无法启动活动 ComponentInfo{com.example.de.vogella.android.todos/com.example.de.vogella.android.todos.TodoDetailActivity}:java.lang.IllegalArgumentException:列“satze”确实不存在

任何人都可以在代码中找到错误吗?谢谢

4

2 回答 2

5

这是你的错误:

private void fillData(Uri uri) {
    String[] projection = { TodoTable.COLUMN_SUMMARY,
            TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY }; //add satze here!
    Cursor cursor = getContentResolver().query(uri, projection, null, null,
            null);
    if (cursor != null) {
        cursor.moveToFirst();
        String category = cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));

        for (int i = 0; i < mCategory.getCount(); i++) {

            String s = (String) mCategory.getItemAtPosition(i);
            if (s.equalsIgnoreCase(category)) {
                mCategory.setSelection(i);
            }
        } 

        mTitleText.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
        mBodyText.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
        mSatzText.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(TodoTable.COLUMN_SATZE)));//you don't have satze in projection!

        // Always close the cursor
        cursor.close();
    }
}

您正在尝试阅读TodoTable.COLUMN_SATZE,但您在投影中忘记了它:请更改此行:

String[] projection = { TodoTable.COLUMN_SUMMARY,
            TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };

进入这个:

String[] projection = { TodoTable.COLUMN_SUMMARY,
                TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY, TodoTable.COLUMN_SATZE };
于 2012-07-26T16:59:40.303 回答
4

在您的CREATE TABLE声明中,您的列名和列类型之间需要空格。

于 2012-07-26T14:46:40.447 回答