Sqlcipher - 关闭后无法再次打开应用程序

时间:2016-10-27 20:57:10

标签: android sqlite sqlcipher

当我第一次运行该应用程序工作正常。但是当我再次尝试打开时,应用程序会出错。我找不到解决方案

我的databasehelper.java
    公共类DatabaseHelper扩展了SQLiteOpenHelper {

    private SQLiteDatabase myDB;
    private Context context;
    public static String DB_NAME = "veri_sql2";
    public static String DB_PATH = "/data/data/appinventor.ai_kksal55.Fikralar10000/databases/";
    public static final int DB_VERSION = 1;
    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION, new DBHook());
        myDB.loadLibs(context);
        this.context = context;
    }
    static class DBHook implements SQLiteDatabaseHook {
        public void preKey(SQLiteDatabase database) {
            database.execSQL("PRAGMA cipher_default_kdf_iter = '4000'");
        }
        public void postKey(SQLiteDatabase database) {      }
    };
    public void encryptDataBase(String passphrase) throws IOException {
        File originalFile = context.getDatabasePath(DB_NAME);
        File newFile = File.createTempFile("sqlcipherutils", "tmp", context.getCacheDir());
        SQLiteDatabase myDB=SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(),"", null,SQLiteDatabase.OPEN_READWRITE);
        myDB.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",newFile.getAbsolutePath(), passphrase));
        myDB.rawExecSQL("SELECT sqlcipher_export('encrypted');");
        myDB.rawExecSQL("DETACH DATABASE encrypted;");
        myDB.close();
        myDB = SQLiteDatabase.openDatabase(newFile.getAbsolutePath(), passphrase, null, SQLiteDatabase.OPEN_READWRITE);
        myDB.rawExecSQL("pragma cipher_default_kdf_iter = 4000;");
        myDB.close();
        originalFile.delete();
        newFile.renameTo(originalFile);
    }
    private boolean checkDataBase() {
        File databasePath = context.getDatabasePath(DB_NAME);
        return databasePath.exists();
    }
    public void copyDataBase() throws IOException {
        try {
            File f = context.getDatabasePath(DB_NAME);
            InputStream in = context.getAssets().open(DB_NAME);
            OutputStream out = new FileOutputStream(f.getAbsolutePath());
            byte[] buffer = new byte[1024];
            int length;
            while ((length = in.read(buffer)) > 0) {
                out.write(buffer, 0, length);
            }
            out.flush();
            out.close();
            in.close();
            encryptDataBase("kksal");
        } catch (Exception e) {
            Log.e("copy database", e.getMessage());
        }

    }
    public void openDataBase(String passphrase) throws SQLException {
        String myPath = DB_PATH + DB_NAME;
        myDB = SQLiteDatabase.openDatabase(myPath, passphrase, null, SQLiteDatabase.OPEN_READWRITE);
    }
    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();

        if (dbExist) {
        } else {
            this.getReadableDatabase("");
            try {
                copyDataBase();
            } catch (IOException e) {
                Log.e("create database", e.getMessage());
            }
        }
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

和MainActivity.java

public class MainActivity extends Activity   {
    private ProgressDialog progressDialog;  
    Cursor c=null;
    private DatabaseHelper kategoriler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        DatabaseHelper myDbHelper = new DatabaseHelper(MainActivity.this);
        try { myDbHelper.createDataBase();}
        catch (IOException ioe) {throw new Error("Veritabanı oluşturulamadı! Uygulamayı yeniden başlatınız");}
        try { myDbHelper.openDataBase("kksal");}
        catch(SQLException sqle){   throw sqle; }
        Intent intent = new Intent("appinventor.ai_kksal55.Fikralar10000.ANAEKRAN");
        startActivity(intent);
        finish();
        //new LoadViewTask().execute();


    }

成功复制SQLite文件。 数据库已加密。并访问记录。一切都很正常。但是我关闭了应用程序。它不会再打开。它在以下行中给出错误。 在databasehelper.java中

myDB = SQLiteDatabase.openDatabase(myPath, passphrase, null, SQLiteDatabase.OPEN_READWRITE);

如果它在我不使用DBHook()时有效。如果我删除dbhook查询需要很长时间。

屏幕上出现

错误

E/Database: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
            net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
                at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
                at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
                at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
                at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:83)
                at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
                at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
                at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1787)
                at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1752)
                at net.sqlcipher.database.SQLiteDatabase.keyDatabase(SQLiteDatabase.java:2427)
                at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2356)
                at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1116)
                at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1083)
                at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1032)
                at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
                at appinventor.ai_kksal55.Fikralar10000.DatabaseHelper.openDataBase(DatabaseHelper.java:75)
                at appinventor.ai_kksal55.Fikralar10000.MainActivity.onCreate(MainActivity.java:29)
                at android.app.Activity.performCreate(Activity.java:5387)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2351)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2449)
                at android.app.ActivityThread.access$800(ActivityThread.java:151)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
                at android.os.Handler.dispatchMessage(Handler.java:110)
                at android.os.Looper.loop(Looper.java:193)
                at android.app.ActivityThread.main(ActivityThread.java:5353)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:515)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
                at dalvik.system.NativeStart.main(Native Method)

我该怎么做才能解决此错误。

0 个答案:

没有答案