Android SQLite DatabaseHelper 未知错误(代码 14):无法打开数据库

Android SQLite DatabaseHelper unknown error (code 14): Could not open database

我正在尝试使用此 DBManager 作为 SQLite 数据库助手。问题是它确实创建了数据库,但首先抛出了这个错误。我不知道如何在不遇到此错误的情况下创建数据库。

注:有类似问题但是没有解决这个问题。它不会抛出写外部存储权限异常。

这是我的数据库助手 class :

 public class DBManager extends SQLiteOpenHelper {
   private static final String TAG = DBManager.class.getSimpleName();

  // All Static variables
  // Database Version
  private static final int DATABASE_VERSION = 1;

  // Database Name
  private static final String DATABASE_NAME = "iap";

  // Login table name
  private static final String TABLE_STORIES = "stories";
  private ArrayList<Story> storiesList = new ArrayList<>();
  private Context mContext;

  public DBManager(Context context) {
     super(context, DATABASE_NAME, null, DATABASE_VERSION);
     mContext = context;
  }

  // Creating Tables
  @Override
  public void onCreate(SQLiteDatabase db) {
     if(checkDataBase()){
        Log.d(TAG, "Database exists and readable");

     }else {

        String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_STORIES + "("
                + KEY_ID + " INTEGER PRIMARY KEY,"
                + KEY_TITLE + " TEXT,"
                + KEY_PIC + " TEXT,"
                + KEY_EXTERNAL_LINK + " TEXT,"
                + KEY_EXTERNAL_TITLE + " TEXT,"
                + KEY_PIC_CREDIT_LINK + " TEXT,"
                + KEY_PIC_CREDIT_TITLE + " TEXT,"
                + KEY_DATE + " TEXT)";
        db.execSQL(CREATE_LOGIN_TABLE);

        Log.d(TAG, "Database tables created");
     }

  }

  /**
   * Check if the database exist and can be read.
   *
   * @return true if it exists and can be read, false if it doesn't
   */
  private boolean checkDataBase() {
     SQLiteDatabase checkDB = null;
     try {
        checkDB = SQLiteDatabase.openDatabase(DATABASE_NAME, null,
                SQLiteDatabase.OPEN_READONLY);
        checkDB.close();
     } catch (SQLiteException e) {
        e.printStackTrace();
     }
     return checkDB != null;
     /*File dbFile = mContext.getDatabasePath(DATABASE_NAME);
     return dbFile.exists();*/
  }

  // Upgrading database
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
     // Drop older table if existed
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_STORIES);

     // Create tables again
     onCreate(db);
  }
}

这是日志(见最后一行):

04-13 16:07:12.918 10920-10920/news.inapic.app E/SQLiteLog: (14) cannot open file at line 32456 of [bda77dda96]
       04-13 16:07:12.918 10920-10920/news.inapic.app E/SQLiteLog: (14) os_unix.c:32456: (2) open(//iap) - 
       04-13 16:07:12.919 10920-10920/news.inapic.app E/SQLiteDatabase: Failed to open database 'iap'.
       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:209)
       at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
       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:808)
       at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)
       at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
       at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
       at news.inapic.app.Helpers.DBManager.checkDataBase(DBManager.java:82)
       at news.inapic.app.Helpers.DBManager.onCreate(DBManager.java:53)
       at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
       at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
       at news.inapic.app.Helpers.DBManager.getStories(DBManager.java:139)
       at news.inapic.app.Acitivity.MainActivity.setupViewPager(MainActivity.java:240)
       at news.inapic.app.Acitivity.MainActivity.onCreate(MainActivity.java:209)
       at android.app.Activity.performCreate(Activity.java:6679)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6119)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:808)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at news.inapic.app.Helpers.DBManager.checkDataBase(DBManager.java:82)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at news.inapic.app.Helpers.DBManager.onCreate(DBManager.java:53)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at news.inapic.app.Helpers.DBManager.getStories(DBManager.java:139)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at news.inapic.app.Acitivity.MainActivity.setupViewPager(MainActivity.java:240)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at news.inapic.app.Acitivity.MainActivity.onCreate(MainActivity.java:209)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.app.Activity.performCreate(Activity.java:6679)
       04-13 16:07:12.919 10920-10920/news.inapic.app W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.app.ActivityThread.-wrap12(ActivityThread.java)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.os.Looper.loop(Looper.java:154)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6119)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
       04-13 16:07:12.920 10920-10920/news.inapic.app W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
       04-13 16:07:12.921 10920-10920/news.inapic.app D/DBManager: Database tables created

您可以创建一个静态实例方法来访问数据库作为单例 class 模式。

public static DBManager instance;

/** Get instance of current database.*/
public static DBManager getInstance(Context context){
 if(instace==null){
   instance= new DBManager(context, DATABASE_NAME, null, DATABASE_VERSION);
}
  return instace;
  }

并且在创建时您不需要检查数据库是否打开。它会给你一个错误,因为你试图在创建之前访问数据库。希望对您有所帮助。

不需要检查onCreate()中是否存在数据库。您可以假设:

  • 数据库存在
  • 以读写模式打开
  • onConfigure() 已被调用
  • 您正在进行交易

此外,使用 SQLiteOpenHelper

的单个实例被认为是一种很好的做法