База данных SQLite из папки активов не работает в Android Pie, т.е. API 28 - PullRequest
0 голосов
/ 28 ноября 2018

Я добавил файл sqlite в папку с активами и использовал данные из файла sqlite в своем приложении.Работает нормально до API 27 т.е. нуги.Но приложение рушится для Android Pie, т.е. API 28. Я использую следующие методы в своем классе помощника базы данных следующим образом.Пожалуйста, помогите мне.

    public Database(Context context, String databaseName) {
             super(context, databaseName, null, DATABASE_VERSION);
             this.context = context;
             String packageName = context.getPackageName();
             DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
             DB_NAME = databaseName;
             openDataBase();
           }

         public void createDataBase() {
             boolean dbExist = checkDataBase();
             if (!dbExist) {
               this.getReadableDatabase();
               try {
                 copyDataBase();
               } catch (IOException e) {
                 Log.e(this.getClass().toString(), "Copying error");
                 throw new Error("Error copying database!");
               }
             }else{
               SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
               int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
               if (DATABASE_VERSION != dbVersion) {
                 File dbFile = context.getDatabasePath(DB_NAME);
                 if (dbFile.delete()) {
                   database.deleteDatabase(new File(DB_PATH + DB_NAME));
                   openDataBase();
                 }
               }
             }
           }

 private boolean checkDataBase() {
     SQLiteDatabase checkDb = null;
     try {
       String path = DB_PATH + DB_NAME;
       //checkDb = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
       checkDb = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
     } catch (SQLException e) {
       Log.d(TAG, "Error while checking db");
     }
     if (checkDb != null) {
       checkDb.close();
     }
     return checkDb != null;
   }

   private void copyDataBase() throws IOException {
     InputStream externalDbStream = context.getAssets().open(DB_NAME);

     String outFileName = DB_PATH + DB_NAME;

     OutputStream localDbStream = new FileOutputStream(outFileName);

     byte[] buffer = new byte[1024];
     int bytesRead;
     while ((bytesRead = externalDbStream.read(buffer)) > 0) {
       localDbStream.write(buffer, 0, bytesRead);
     }
     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
     SharedPreferences.Editor editor = prefs.edit();
     editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
     editor.commit();
     localDbStream.close();
     externalDbStream.close();
   }


    public SQLiteDatabase openDataBase() throws SQLException {

         String path = DB_PATH + DB_NAME;
         if (database == null) {
         createDataBase();
         database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
       }
      return database;
     }

Это методы openDatabase, copyDatabase и создания базы данных, которые я использую.

Это журнал сбоев -

android.database.sqlite.SQLiteException: такой таблицы нет: quran_chapters (код 1 SQLITE_ERROR): во время компиляции: SELECT * FROM quran_chapters в android.database.sqlite.SQLiteConnection.nativePrepareStatement (собственный метод) в android.database.sqlite.SQLquirePectionPrease(SQLiteConnection.java:903) в android.database.sqlite.SQLiteConnection.prepare (SQLiteConnection.java:514) в android.database.sqlite.SQLiteSession.prepare (SQLiteSession.java:588) в android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58) по адресу android.database.sqlite.SQLiteQuery. (SQLiteQuery.java:37) по адресу android.database.sqlite.SQLiteDirectCursorDriver.query (SQLiteDirectCursorDriver.java:46) по адресу android.database.sqlite.QQuery.SQLiteDQ(SQLiteDatabase.java:1408) в android.database.sqlite.SQLiteDatabase.rawQuery (SQLiteDatabase.java:1347)

1 Ответ

0 голосов
/ 28 ноября 2018

Если база данных не существует, вы затем используете this.getReadableDatabase (); , которая создаст базу данных, и, поскольку вы, вероятно, ничего не сделали в методе onCreate, база данных пуста.

Затем вы перезаписываете диск копией, однако, поскольку база данных все еще открыта (this.getReadableDatabase();), пустая база данных без таблиц может быть полностью сохранена в кеше, и, следовательно, проблема.

Использованиеозначает, что открыть базу данных, когда база данных не существует, - это попытка обойти проблему, связанную с ошибкой копирования, когда она является первой базой данных, и на этом этапе хранилище приложения не имеет каталога с именем database (открытие открывает каталог).

  • Обратите внимание, что в большинстве случаев getReadableDatabase получит доступную для записи базу данных.

Лично я предпочитаю и не сталкивался с какими-либо проблемами., по: -

  1. Никогда не кодируйте путь к базе данных жестко, скорее всегда используйте метод Context getDatabasePath .Например: - mDBPath = context.getDatabasePath(database).getPath();
  2. Проверка, существует ли файл базы данных, чтобы увидеть, существует ли база данных, вместо открытия базы данных, чтобы увидеть, существует ли она.(см. пример для 3)

  3. Проверка родительского элемента базы данных (то есть папки базы данных), чтобы определить, существует ли она, и если не используется метод File mkdirs длясоздать каталог баз данных.например: -

    private boolean ifDatabaseExists(String dbpath) { File db = new File(dbpath); if(db.exists()) return true; File dir = new File(db.getParent()); if (!dir.exists()) { dir.mkdirs(); } return false; }

  4. Копирование базы данных из активов в расположение, указанное путем, полученным в 1.

    • Как часть 4 я получаю файл ресурса, проверьте первые 16 байтов, чтобы увидеть, является ли это действительной базой данных SQLite (должен быть «формат SQLite 3 \ u0000»).

    • а затем перейдите к копированию базы данных из ресурса в файл базы данных.

...