1

为了开始在我正在开发的应用程序中使用 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 类实例的 onUpgrade() 方法中放置了一些迁移代码。不幸的是,虽然我升级了数据库版本号,但我还是调用了: getInstance().getReadableDatabase("testKey"); onUpgrade() 和 onCreate() 方法都不会被调用。我错过了配置中的某些内容吗?

4

2 回答 2

0

就像您第一次在以前未加密的数据库中使用密码一样,我建议您强制重新创建数据库。

为此,您只需在 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.
   }

}
于 2018-03-15T21:43:08.383 回答
0

最后我找到了问题的解决方案。我没有在 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);
  }
}

我从这个来源获取了解决方案。感谢作者,不管他是谁!

于 2018-03-21T14:11:12.833 回答