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

时间:2014-10-20 17:31:25

标签: java android

我正在使用内容提供商来记笔记类型的应用。当我在内容提供商中只有一个表时它工作正常,但现在我已经添加了另一个表,我必须弄乱一些东西。我能读,写&在应用程序中删除,但当我尝试单击列表项以更新/编辑该条目时,应用程序崩溃告诉我有无效的表。

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

这是我的代码:

内容提供商



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;
&#13;
&#13;

CustomerEdit.java

&#13;
&#13;
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;
&#13;
&#13;

NoteTable.java

&#13;
&#13;
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;
&#13;
&#13;

DeviceTable.java

&#13;
&#13;
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;
&#13;
&#13;

我的数据库助手

&#13;
&#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;
&#13;
&#13;

如果任何人可以看到我可能遗失的任何东西,请告诉我,我是编程的新手,我真的在为此辩护。提前谢谢。

1 个答案:

答案 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;
      }