I'm trying to build a notepad app referring http://www.valokafor.com/create-android-notepad-app-part-2/ . My launcher activity is the list of notes but it's giving this error when I try to run the app -
Caused by: java.lang.IllegalStateException: Invalid tables
at com.example.android.sqlitedbase.data.NoteContentProvider.query(NoteContentProvider.java:70)
Line 70 in NoteContentProvider.java in the method -
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
is
cursor.setNotificationUri(getContext().getContentResolver(), uri);
There is no note initially in the list and it tries to fetch one from memory which possibly leads to this error. Following are the contents of the NoteContentProvider.java
public class NoteContentProvider extends ContentProvider {
private DatabaseHelper dbHelper;
private static final String BASE_PATH_NOTE = "notes";
private static final String AUTHORITY = "com.example.android.sqlitedbase.data.NoteContentProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH_NOTE);
private static final int NOTE = 100;
private static final int NOTES = 101;
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static {
URI_MATCHER.addURI(AUTHORITY, BASE_PATH_NOTE, NOTES);
URI_MATCHER.addURI(AUTHORITY, BASE_PATH_NOTE + "/#", NOTE);
}
private void checkColumns(String[] projection) {
if (projection != null) {
HashSet<String> request = new HashSet<String>(Arrays.asList(projection));
HashSet<String> available = new HashSet<String>(Arrays.asList(Constants.COLUMNS));
if (!available.containsAll(request)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
@Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
checkColumns(projection);
int type = URI_MATCHER.match(uri);
switch (type){
case NOTE:
//there is not to do if the query is for the table
break;
case NOTES:
queryBuilder.appendWhere(Constants.COLUMN_ID + " = " + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri); // Line 70 which causes error in Logcat
return cursor;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
Long id;
switch (type){
case NOTES:
id = db.insert(Constants.NOTES_TABLE, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH_NOTE + "/" + id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
int affectedRows;
switch (type) {
case NOTES:
affectedRows = db.delete(Constants.NOTES_TABLE, selection, selectionArgs);
break;
case NOTE:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
affectedRows = db.delete(Constants.NOTES_TABLE, Constants.COLUMN_ID + "=" + id, null);
} else {
affectedRows = db.delete(Constants.NOTES_TABLE, Constants.COLUMN_ID + "=" + id + " and " + selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return affectedRows;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
int affectedRows;
switch (type) {
case NOTES:
affectedRows = db.update(Constants.NOTES_TABLE, values, selection, selectionArgs);
break;
case NOTE:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
affectedRows = db.update(Constants.NOTES_TABLE, values, Constants.COLUMN_ID + "=" + id, null);
} else {
affectedRows = db.update(Constants.NOTES_TABLE, values, Constants.COLUMN_ID + "=" + id + " and " + selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return affectedRows;
}
}
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper
{
private static final String DATABASE_NAME="simple_note_app.db";
private static final int DATABASE_VERSION=1;
private static final String COLUMN_ID="_id";
private static final String COLUMN_NAME="name";
private static final String COLUMN_TITLE="title";
private static final String COLUMN_CONTENT="content";
private static final String COLUMN_MODIFIED_TIME="modified_time";
private static final String COLUMN_CREATED_TIME="created_time";
private static final String CREATE_TABLE_NOTE="create table note"
+"("+COLUMN_ID+" integer primary key autoincrement, "
+ COLUMN_TITLE+" text not null, "
+COLUMN_CONTENT+" text not null, "
+COLUMN_MODIFIED_TIME+" integer not null, "
+COLUMN_CREATED_TIME+" integer not null "+")";
public DatabaseHelper(Context context)
{
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_NOTE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
The issue is probably, since you have made changes to the database schema several times when you try to run the application several times on your device. it might have messed things up there.
One easy option to see this is the issue, try uninstalling the app and re run the application from the scratch.
That is why you have a
DATABASE_VERSION
andto handle this sort of situations.
OH WAIT,
Or there may be a mistake in table creation string- a conflict of
note
andnotes
and withConstants.NOTES_TABLE
Please change the clause above to the clause below. That is, change to a single / aftercontent: