我正在使用内容提供商来记笔记类型的应用。当我在内容提供商中只有一个表时它工作正常,但现在我已经添加了另一个表,我必须弄乱一些东西。我能读,写&在应用程序中删除,但当我尝试单击列表项以更新/编辑该条目时,应用程序崩溃告诉我有无效的表。
我知道这些表格无效,因为它在我创建新条目时会识别它们。我相信这与我的内容提供商有关,因为它在我尝试添加第二个表之前一直运行良好。
这是我的代码:
内容提供商
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");
}
}
}
}
&#13;
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();
}
}
&#13;
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);
}
}
&#13;
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);
}
}
&#13;
我的数据库助手
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,
// e.g. 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);
}
}
&#13;
如果任何人可以看到我可能遗失的任何东西,请告诉我,我是编程的新手,我真的在为此辩护。提前谢谢。
答案 0 :(得分:0)
我想出了这个问题。似乎我的查询集表设置得不是很正确。我不得不补充一下 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;
}