Android SQLiteCantOpenDatabaseExeption 由于未知错误
Android SQLiteCantOpenDatabaseExeption due to unknown error
我正在尝试编写一个 android 应用程序来扩展 SQLiteOpenHelper class。不幸的是,由于 SQLiteCantOpenDatabaseException,我有一个 android 测试每次都失败。
这是扩展 SQLiteOpenHelper 的数据库助手 class:
public class ToDoDbHelper extends SQLiteOpenHelper {
// must be incremented upon schema change
private static final int DATABASE_VERSION = 1;
static final String DATABASE_NAME = "todo.db";
private final Context mContext;
public ToDoDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
// database already exists
if(dbFile.exists()) {
return;
}
// Create a table to hold our labels
final String SQL_CREATE_LABEL_TABLE = "CREATE TABLE" + TaskLabel.TABLE_NAME + " (" +
TaskLabel._ID + " INTEGER PRIMARY KEY," +
TaskLabel.COLUMN_LABEL + " TEXT NOT NULL " +
" );";
// Create a table to hold our priorities
final String SQL_CREATE_PRIORITY_TABLE = "CREATE TABLE" + TaskPriority.TABLE_NAME + " (" +
TaskPriority._ID + " INTEGER PRIMARY KEY," +
TaskPriority.COLUMN_PRIORITY + " TEXT NOT NULL " +
" );";
final String SQL_INSERT_PRIORITY_TABLE = "INSERT INTO " + TaskLabel.TABLE_NAME +
" VALUES (" + Resources.getSystem().getString(R.string.priority_none) + ")," +
" (" + Resources.getSystem().getString(R.string.priority_low) + ")," +
" (" + Resources.getSystem().getString(R.string.priority_med) + ")," +
" (" + Resources.getSystem().getString(R.string.priority_high) +
");";
// Create a table to hold our tasks
final String SQL_CREATE_TASK_TABLE = "CREATE TABLE " + TaskEntry.TABLE_NAME + " (" +
TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
TaskEntry.COLUMN_CREATE_DATE + " INTEGER NOT NULL," +
TaskEntry.COLUMN_DUE_DATE + " INTEGER," +
TaskEntry.COLUMN_TITLE + " TEXT NOT NULL," +
TaskEntry.COLUMN_DETAIL + " TEXT," +
TaskEntry.COLUMN_IS_COMPLETED + " INTEGER NOT NULL," +
TaskEntry.COLUMN_IS_DELETED + " INTEGER NOT NULL," +
TaskEntry.COLUMN_REMINDER_ADDED + " INTEGER NOT NULL," +
TaskEntry.COLUMN_LABEL_ID + " INTEGER NOT NULL," +
TaskEntry.COLUMN_PRIORITY_ID + " INTEGER NOT NULL," +
TaskEntry.COLUMN_PARENT_TASK_ID + " INTEGER," +
// Set up the priority column as a foreign key to the priority table
" FOREIGN KEY (" + TaskEntry.COLUMN_PRIORITY_ID + ") REFERENCES " +
TaskPriority.TABLE_NAME + "(" + TaskPriority._ID + "), " +
// Set up label column as a foreign key to the label table
" FOREIGN KEY (" + TaskEntry.COLUMN_LABEL_ID + ") REFERENCES " +
TaskLabel.TABLE_NAME + "(" + TaskLabel._ID + "));";
sqLiteDatabase.execSQL(SQL_CREATE_LABEL_TABLE);
sqLiteDatabase.execSQL(SQL_CREATE_PRIORITY_TABLE);
sqLiteDatabase.execSQL(SQL_INSERT_PRIORITY_TABLE);
sqLiteDatabase.execSQL(SQL_CREATE_TASK_TABLE);
}
// this function to be implemented if DATABASE_VERSION is incremented (i.e. if schema changes)
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
下面是调用 class:
的测试
@Test
public void testCreateDb() throws Throwable {
mContext.deleteDatabase(ToDoDbHelper.DATABASE_NAME);
SQLiteDatabase db = new ToDoDbHelper(
mContext).getWritableDatabase();
// make sure the database is open
assertEquals(true, db.isOpen());
异常发生在这一行:
SQLiteDatabase db = new ToDoDbHelper(
mContext).getWritableDatabase();
这里是堆栈跟踪:
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error
(code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:207)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:191)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:571)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.todo.group1.todo.data.TestDb.testCreateDb(TestDb.java:47)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)
我试过:
- 正在清除应用程序数据
- 正在卸载
- 运行 在模拟器而不是我的设备上进行测试
- 正在重命名数据库文件
- 向 Android 清单添加 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限。
但是无论我做什么,都会抛出异常并且永远不会创建数据库(永远不会调用 onCreate())。我应该怎么办?感谢任何帮助。
我发现您在两个 SQL 创建查询中遗漏了一个空白。
例如:
final String SQL_CREATE_LABEL_TABLE = "CREATE TABLE" // you missing a blank after TABLE
请再次仔细检查所有声明:)
决定将我的评论作为答案放在这里,因为它解决了问题并且将来可能会帮助其他人:
在 Android 6+ (M) 您应该在运行时请求权限以访问数据库。 Android 开发人员指南:https://developer.android.com/training/permissions/requesting.html
我正在尝试编写一个 android 应用程序来扩展 SQLiteOpenHelper class。不幸的是,由于 SQLiteCantOpenDatabaseException,我有一个 android 测试每次都失败。
这是扩展 SQLiteOpenHelper 的数据库助手 class:
public class ToDoDbHelper extends SQLiteOpenHelper {
// must be incremented upon schema change
private static final int DATABASE_VERSION = 1;
static final String DATABASE_NAME = "todo.db";
private final Context mContext;
public ToDoDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
// database already exists
if(dbFile.exists()) {
return;
}
// Create a table to hold our labels
final String SQL_CREATE_LABEL_TABLE = "CREATE TABLE" + TaskLabel.TABLE_NAME + " (" +
TaskLabel._ID + " INTEGER PRIMARY KEY," +
TaskLabel.COLUMN_LABEL + " TEXT NOT NULL " +
" );";
// Create a table to hold our priorities
final String SQL_CREATE_PRIORITY_TABLE = "CREATE TABLE" + TaskPriority.TABLE_NAME + " (" +
TaskPriority._ID + " INTEGER PRIMARY KEY," +
TaskPriority.COLUMN_PRIORITY + " TEXT NOT NULL " +
" );";
final String SQL_INSERT_PRIORITY_TABLE = "INSERT INTO " + TaskLabel.TABLE_NAME +
" VALUES (" + Resources.getSystem().getString(R.string.priority_none) + ")," +
" (" + Resources.getSystem().getString(R.string.priority_low) + ")," +
" (" + Resources.getSystem().getString(R.string.priority_med) + ")," +
" (" + Resources.getSystem().getString(R.string.priority_high) +
");";
// Create a table to hold our tasks
final String SQL_CREATE_TASK_TABLE = "CREATE TABLE " + TaskEntry.TABLE_NAME + " (" +
TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
TaskEntry.COLUMN_CREATE_DATE + " INTEGER NOT NULL," +
TaskEntry.COLUMN_DUE_DATE + " INTEGER," +
TaskEntry.COLUMN_TITLE + " TEXT NOT NULL," +
TaskEntry.COLUMN_DETAIL + " TEXT," +
TaskEntry.COLUMN_IS_COMPLETED + " INTEGER NOT NULL," +
TaskEntry.COLUMN_IS_DELETED + " INTEGER NOT NULL," +
TaskEntry.COLUMN_REMINDER_ADDED + " INTEGER NOT NULL," +
TaskEntry.COLUMN_LABEL_ID + " INTEGER NOT NULL," +
TaskEntry.COLUMN_PRIORITY_ID + " INTEGER NOT NULL," +
TaskEntry.COLUMN_PARENT_TASK_ID + " INTEGER," +
// Set up the priority column as a foreign key to the priority table
" FOREIGN KEY (" + TaskEntry.COLUMN_PRIORITY_ID + ") REFERENCES " +
TaskPriority.TABLE_NAME + "(" + TaskPriority._ID + "), " +
// Set up label column as a foreign key to the label table
" FOREIGN KEY (" + TaskEntry.COLUMN_LABEL_ID + ") REFERENCES " +
TaskLabel.TABLE_NAME + "(" + TaskLabel._ID + "));";
sqLiteDatabase.execSQL(SQL_CREATE_LABEL_TABLE);
sqLiteDatabase.execSQL(SQL_CREATE_PRIORITY_TABLE);
sqLiteDatabase.execSQL(SQL_INSERT_PRIORITY_TABLE);
sqLiteDatabase.execSQL(SQL_CREATE_TASK_TABLE);
}
// this function to be implemented if DATABASE_VERSION is incremented (i.e. if schema changes)
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
下面是调用 class:
的测试@Test
public void testCreateDb() throws Throwable {
mContext.deleteDatabase(ToDoDbHelper.DATABASE_NAME);
SQLiteDatabase db = new ToDoDbHelper(
mContext).getWritableDatabase();
// make sure the database is open
assertEquals(true, db.isOpen());
异常发生在这一行:
SQLiteDatabase db = new ToDoDbHelper(
mContext).getWritableDatabase();
这里是堆栈跟踪:
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error
(code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:207)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:191)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:571)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.todo.group1.todo.data.TestDb.testCreateDb(TestDb.java:47)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)
我试过:
- 正在清除应用程序数据
- 正在卸载
- 运行 在模拟器而不是我的设备上进行测试
- 正在重命名数据库文件
- 向 Android 清单添加 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限。
但是无论我做什么,都会抛出异常并且永远不会创建数据库(永远不会调用 onCreate())。我应该怎么办?感谢任何帮助。
我发现您在两个 SQL 创建查询中遗漏了一个空白。
例如:
final String SQL_CREATE_LABEL_TABLE = "CREATE TABLE" // you missing a blank after TABLE
请再次仔细检查所有声明:)
决定将我的评论作为答案放在这里,因为它解决了问题并且将来可能会帮助其他人:
在 Android 6+ (M) 您应该在运行时请求权限以访问数据库。 Android 开发人员指南:https://developer.android.com/training/permissions/requesting.html