繁体   English   中英

内容提供程序多表更新时出错

[英]Content Provider Multiple Tables Error on Update

我正在为笔记类型的应用程序使用内容提供商。 当我在内容提供程序中只有一个表时,它工作得很好,但是现在我添加了另一个表,我一定搞砸了。 我可以在应用程序中进行读取,写入和删除,但是当我尝试单击列表项以更新/编辑条目时,应用程序崩溃,告诉我包含无效的表。

我知道这些表不是无效的,因为在创建新条目时它可以识别它们。 我相信这与我的内容提供商有关,因为在我尝试添加第二张表之前,它一直运行良好。

这是我的代码:

内容提供商

 package com.cossioinsurance.rentalsafety.contentprovider2; import java.util.Arrays; import java.util.HashSet; import com.cossioinsurance.rentalsafety.database.TodoDatabaseHelper; import com.cossioinsurance.rentalsafety.database.NoteTable; import com.cossioinsurance.rentalsafety.database.DeviceTable; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; public class MyNoteContentProvider 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 int DEVICES = 30; private static final int DEVICE_ID = 40; private static final String AUTHORITY = "com.cossioinsurance.rentalsafety.contentprovider2"; private static final String BASE_PATH = "todos"; private static final String DEVICE_PATH = "devices"; public static final Uri CONTENT_URI_TODOS = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); public static final Uri CONTENT_URI_DEVICES = Uri.parse("content://" + AUTHORITY + "/" + DEVICE_PATH); public static final String CONTENT_TYPE_TODOS = ContentResolver.CURSOR_DIR_BASE_TYPE + "/todos"; public static final String CONTENT_TYPE_DEVICES = ContentResolver.CURSOR_DIR_BASE_TYPE + "/devices"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo"; //??? public static final String CONTENT_ITEM_TYPE2 = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/device"; private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS); sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID); sURIMatcher.addURI(AUTHORITY, DEVICE_PATH, DEVICES); sURIMatcher.addURI(AUTHORITY, DEVICE_PATH + "/#", DEVICE_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 int uriType = sURIMatcher.match(uri); switch (uriType) { case TODO_ID: // adding the ID to the original query queryBuilder.appendWhere(NoteTable.COLUMN_ID + "=" + uri.getLastPathSegment()); break; case DEVICE_ID: // adding the ID to the original query queryBuilder.appendWhere(DeviceTable.COLUMN_ID + "=" + uri.getLastPathSegment()); break; case TODOS: queryBuilder.setTables(NoteTable.TABLE_TODO); break; case DEVICES: queryBuilder.setTables(DeviceTable.TABLE_DEVICE); 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(NoteTable.TABLE_TODO, null, values); break; case DEVICES: id = sqlDB.insert(DeviceTable.TABLE_DEVICE, null, values); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return Uri.parse(BASE_PATH + "/" + id); } //Deleted Rows @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(NoteTable.TABLE_TODO, selection, selectionArgs); break; case TODO_ID: String id = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsDeleted = sqlDB.delete(NoteTable.TABLE_TODO, NoteTable.COLUMN_ID + "=" + id, null); } else { rowsDeleted = sqlDB.delete(NoteTable.TABLE_TODO, NoteTable.COLUMN_ID + "=" + id + " and " + selection, selectionArgs); } break; case DEVICES: rowsDeleted = sqlDB.delete(DeviceTable.TABLE_DEVICE, selection, selectionArgs); break; case DEVICE_ID: String id2 = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsDeleted = sqlDB.delete(DeviceTable.TABLE_DEVICE, NoteTable.COLUMN_ID + "=" + id2, null); } else { rowsDeleted = sqlDB.delete(NoteTable.TABLE_TODO, NoteTable.COLUMN_ID + "=" + id2 + " and " + selection, selectionArgs); } break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return rowsDeleted; } //Update Rows @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(NoteTable.TABLE_TODO, values, selection, selectionArgs); break; case TODO_ID: String id = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsUpdated = sqlDB.update(NoteTable.TABLE_TODO, values, NoteTable.COLUMN_ID + "=" + id, null); } else { rowsUpdated = sqlDB.update(NoteTable.TABLE_TODO, values, NoteTable.COLUMN_ID + "=" + id + " and " + selection, selectionArgs); } break; case DEVICES: rowsUpdated = sqlDB.update(DeviceTable.TABLE_DEVICE, values, selection, selectionArgs); break; case DEVICE_ID: String id2 = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsUpdated = sqlDB.update(DeviceTable.TABLE_DEVICE, values, DeviceTable.COLUMN_ID + "=" + id2, null); } else { rowsUpdated = sqlDB.update(DeviceTable.TABLE_DEVICE, values, DeviceTable.COLUMN_ID + "=" + id2 + " 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 = { NoteTable.COLUMN_CATEGORY, NoteTable.COLUMN_SUMMARY, NoteTable.COLUMN_DESCRIPTION, NoteTable.COLUMN_EMAIL, NoteTable.COLUMN_RENTALDATES, NoteTable.COLUMN_ENDDATES, NoteTable.COLUMN_TIME, NoteTable.COLUMN_LOCATION, NoteTable.COLUMN_NOTES, NoteTable.COLUMN_ID, DeviceTable.COLUMN_ID, DeviceTable.COLUMN_CATEGORY, DeviceTable.COLUMN_NAME, DeviceTable.COLUMN_TYPE }; 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"); } } } } 

CustomerEdit.java

 package com.cossioinsurance.rentalsafety; import com.cossioinsurance.rentalsafety.contentprovider2.MyNoteContentProvider; import com.cossioinsurance.rentalsafety.database.NoteTable; import android.app.Activity; import com.cossioinsurance.rentalsafety.database.R; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import android.widget.Toast; /* * TodoDetailActivity allows to enter a new todo item * or to change an existing */ public class CustomerEdit extends Activity { private Spinner mCategory; private EditText mTitleText; private EditText mBodyText; private EditText mEmailAddress; private EditText mRentalDates; private EditText mEndDate; private EditText mTime; private EditText mLocationAddress; private EditText mNoteEditText; private Uri todoUri; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.customer_edit); mCategory = (Spinner) findViewById(R.id.category); mTitleText = (EditText) findViewById(R.id.todo_edit_summary); mBodyText = (EditText) findViewById(R.id.phone_number); mEmailAddress = (EditText) findViewById(R.id.emailAddress); mRentalDates = (EditText) findViewById(R.id.rentalDates); mEndDate = (EditText) findViewById(R.id.endDate); mTime = (EditText) findViewById(R.id.time); mLocationAddress = (EditText) findViewById(R.id.locationAddress); mNoteEditText = (EditText) findViewById(R.id.noteEditText); 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(MyNoteContentProvider.CONTENT_ITEM_TYPE); // Or passed from the other activity if (extras != null) { todoUri = extras .getParcelable(MyNoteContentProvider.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 = { NoteTable.COLUMN_SUMMARY, NoteTable.COLUMN_DESCRIPTION, NoteTable.COLUMN_CATEGORY, NoteTable.COLUMN_EMAIL, NoteTable.COLUMN_RENTALDATES, NoteTable.COLUMN_ENDDATES, NoteTable.COLUMN_TIME, NoteTable.COLUMN_LOCATION, NoteTable.COLUMN_NOTES }; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if (cursor != null) { cursor.moveToFirst(); String category = cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.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(NoteTable.COLUMN_SUMMARY))); mBodyText.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_DESCRIPTION))); mEmailAddress.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_EMAIL))); mRentalDates.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_RENTALDATES))); mEndDate.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_ENDDATES))); mTime.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_TIME))); mLocationAddress.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_LOCATION))); mNoteEditText.setText(cursor.getString(cursor .getColumnIndexOrThrow(NoteTable.COLUMN_NOTES))); // always close the cursor cursor.close(); } } protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); saveState(); outState.putParcelable(MyNoteContentProvider.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 email = mEmailAddress.getText().toString(); String rentaldates = mRentalDates.getText().toString(); String enddate = mEndDate.getText().toString(); String time = mTime.getText().toString(); String location = mLocationAddress.getText().toString(); String notes = mNoteEditText.getText().toString(); // only save if either summary or description // is available if (description.length() == 0 && summary.length() == 0) { return; } ContentValues values = new ContentValues(); values.put(NoteTable.COLUMN_CATEGORY, category); values.put(NoteTable.COLUMN_SUMMARY, summary); values.put(NoteTable.COLUMN_DESCRIPTION, description); values.put(NoteTable.COLUMN_EMAIL, email); values.put(NoteTable.COLUMN_RENTALDATES, rentaldates); values.put(NoteTable.COLUMN_ENDDATES, enddate); values.put(NoteTable.COLUMN_TIME, time); values.put(NoteTable.COLUMN_LOCATION, location); values.put(NoteTable.COLUMN_NOTES, notes); if (todoUri == null) { // New todo todoUri = getContentResolver().insert(MyNoteContentProvider.CONTENT_URI_TODOS, values); } else { // Update todo getContentResolver().update(todoUri, values, null, null); } } private void makeToast() { Toast.makeText(CustomerEdit.this, "Please maintain a summary", Toast.LENGTH_LONG).show(); } } 

NoteTable.java

 package com.cossioinsurance.rentalsafety.database; import android.database.sqlite.SQLiteDatabase; import android.util.Log; public class NoteTable { // Database table public static final String TABLE_TODO = "todo"; public static final String COLUMN_ID = "_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_PHONE = "phone"; public static final String COLUMN_EMAIL = "email"; public static final String COLUMN_RENTALDATES = "rentaldates"; public static final String COLUMN_ENDDATES = "enddates"; public static final String COLUMN_TIME = "time"; public static final String COLUMN_LOCATION = "location"; public static final String COLUMN_NOTES = "notes"; // Database creation SQL statement private static final String DATABASE_CREATE = "create table " + TABLE_TODO + "(" + COLUMN_ID + " integer primary key autoincrement, " + COLUMN_CATEGORY + " text not null, " + COLUMN_SUMMARY + " text not null," + COLUMN_DESCRIPTION + " text not null," + COLUMN_EMAIL + " text not null," + COLUMN_RENTALDATES + " text not null," + COLUMN_ENDDATES + " text not null," + COLUMN_TIME + " text not null," + COLUMN_LOCATION + " text not null," + COLUMN_NOTES + " 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(NoteTable.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); } } 

DeviceTable.java

 package com.cossioinsurance.rentalsafety.database; import android.database.sqlite.SQLiteDatabase; import android.util.Log; public class DeviceTable { // Database table public static final String TABLE_DEVICE = "device"; public static final String COLUMN_ID = "_id"; public static final String COLUMN_CATEGORY = "category"; public static final String COLUMN_NAME = "name"; public static final String COLUMN_TYPE = "type"; // Database creation SQL statement private static final String DATABASE_CREATE = "create table " + TABLE_DEVICE + "(" + COLUMN_ID + " integer primary key autoincrement, " + COLUMN_CATEGORY + " text not null, " + COLUMN_NAME + " text not null," + COLUMN_TYPE + " 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(DeviceTable.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); database.execSQL("DROP TABLE IF EXISTS " + TABLE_DEVICE); onCreate(database); } } 

还有我的数据库助手

 package com.cossioinsurance.rentalsafety.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; 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) { NoteTable.onCreate(database); DeviceTable.onCreate(database); } // Method is called during an upgrade of the database, // eg if you increase the database version @Override public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { NoteTable.onUpgrade(database, oldVersion, newVersion); DeviceTable.onUpgrade(database, oldVersion, newVersion); } } 

如果有人能看到我可能会丢失的任何东西,请告诉我,我是编程新手,我真的为此感到不知所措。 先感谢您。

我发现了问题。 看来我的查询集表设置不正确。 我必须添加queryBuilder.setTables(NoteTable.TABLE_TODO); 查询中的所有情况。 我以前没有将该语句添加到_ID案例中。

 @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


        int uriType = sURIMatcher.match(uri);
        switch (uriType) {
        case TODOS:
            queryBuilder.setTables(NoteTable.TABLE_TODO);
          break;
        case TODO_ID:
            queryBuilder.setTables(NoteTable.TABLE_TODO);
          // adding the ID to the original query
          queryBuilder.appendWhere(NoteTable.COLUMN_ID + "="
              + uri.getLastPathSegment());
          break;
        case DEVICES:
            queryBuilder.setTables(DeviceTable.TABLE_DEVICE);
          break;
        case DEVICE_ID:
            queryBuilder.setTables(DeviceTable.TABLE_DEVICE);
          // adding the ID to the original query
          queryBuilder.appendWhere(DeviceTable.COLUMN_ID + "="
              + 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;
      }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM