将 android.database.sqlite.SQLiteOpenHelper 更改为 net.sqlcipher.database.SQLiteOpenHelper 后未调用 onUpgrade 和 onCreate
onUpgrade and onCreate not being called after changing android.database.sqlite.SQLiteOpenHelper to net.sqlcipher.database.SQLiteOpenHelper
我一直在关注 official documentation 以便开始在我开发的应用程序中使用 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。
由于我的应用程序已经发布,我还在我的 SQLiteOpenHelper class 实例的 onUpgrade() 方法中放置了一些迁移代码。
不幸的是,虽然我升级了数据库版本号,但我还是调用了:
getInstance().getReadableDatabase("testKey");
onUpgrade() 和 onCreate() 方法都不会被调用。
我是否遗漏了配置中的某些内容?
如果您是第一次在之前的 non-ciphered 数据库中使用密码,那么我建议您将数据库强制设置为 re-created。
为此,您只需在 DatabaseHelper class 中更改数据库名称即可。更改数据库名称后,当您的设备更新时,将触发 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.
}
}
终于找到了解决问题的方法。我没有在 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);
}
}
我从这个 source 中得到了解决方案。感谢作者,不管他是谁!
我一直在关注 official documentation 以便开始在我开发的应用程序中使用 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。
由于我的应用程序已经发布,我还在我的 SQLiteOpenHelper class 实例的 onUpgrade() 方法中放置了一些迁移代码。
不幸的是,虽然我升级了数据库版本号,但我还是调用了:
getInstance().getReadableDatabase("testKey");
onUpgrade() 和 onCreate() 方法都不会被调用。
我是否遗漏了配置中的某些内容?
如果您是第一次在之前的 non-ciphered 数据库中使用密码,那么我建议您将数据库强制设置为 re-created。
为此,您只需在 DatabaseHelper class 中更改数据库名称即可。更改数据库名称后,当您的设备更新时,将触发 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.
}
}
终于找到了解决问题的方法。我没有在 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);
}
}
我从这个 source 中得到了解决方案。感谢作者,不管他是谁!