onUpgrade и onCreate не вызывают после изменения android.database.sqlite.SQLiteOpenHelper в net.sqlcipher.database.SQLiteOpenHelper

Я следовал официальной документации, чтобы начать использовать SQLCipher Community Edition в приложениях, которые разрабатываю. Итак, я сделал правильный импорт gradle следующим образом:

compile 'net.zetetic:android-database-sqlcipher:3.5.9@aar'

Я добавил

@Override
public void onCreate() {
   super.onCreate();
   SQLiteDatabase.loadLibs(this);
}

в MainApplication.java. Поскольку мои приложения уже выпущены, я поместил также некоторый код миграции в метод onUpgrade() в моем экземпляре класса SQLiteOpenHelper. К сожалению, хотя я обновил номер версии БД, я делаю вызов:getInstance().getReadableDatabase("testKey"); методы onUpgrade() и onCreate() не будут вызваны. Я что-то упустил в конфигурации?

2 ответа

Решение

Наконец я нашел решение проблемы. Вместо вызова функции миграции внутри метода onUpgrade() я добавил код миграции перед первым запросом к базе данных (после открытия приложения):

public static void encrypt(Context ctxt, File originalFile, char[] 
passphrase)
throws IOException {
SQLiteDatabase.loadLibs(ctxt);

if (originalFile.exists()) {
  File newFile=
  File.createTempFile("sqlcipherutils", "tmp", ctxt.getCacheDir());
   SQLiteDatabase db=
   SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(), "", null, SQLiteDatabase.OPEN_READWRITE);

   db.rawExecSQL("ATTACH DATABASE '" + newFile.getAbsolutePath()+ "' AS encrypted KEY '"+String.valueOf(passphrase)+"'");
   db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
   db.rawExecSQL("DETACH DATABASE encrypted");

   int version=db.getVersion();

    db.close();

    db=SQLiteDatabase.openDatabase(newFile.getAbsolutePath(), passphrase, null, SQLiteDatabase.OPEN_READWRITE);
    db.setVersion(version);
    db.close();

    originalFile.delete();
    newFile.renameTo(originalFile);
  }
}

Я взял решение из этого источника. Спасибо автору, кем бы он ни был!

Если вы впервые используете шифр в ранее незашифрованной базе данных, то я рекомендую вам принудительно создать базу данных заново.

Для этого вы можете просто изменить имя вашей базы данных в вашем классе DatabaseHelper. После того, как вы измените имя базы данных, при обновлении вашего устройства сработает onCreate(), и она создаст всю вашу базу данных с нуля.

public class YourDatabaseHelper extends SQLiteOpenHelper {

   public final static String DATABASE_NAME = Constants.DATABASE_NAME; // Change the name to force the database to be created from zero.
   public final static int CURRENT_VERSION = Constants.DATABASE_VERSION_INT;


   public DatabaseHelper(Context context){
       super(context, DATABASE_NAME, null, CURRENT_VERSION);        
   }

   public void onCreate(SQLiteDatabase db){
       // Create all your tables.
   }

   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
       // No need to do anything in here, because onCreate will be triggered.
   }

}
Другие вопросы по тегам