Sqlcipher __ CREATE TABLE android_metadata failed

前端 未结 2 1174
Happy的楠姐
Happy的楠姐 2021-01-22 20:28

I\'m trying to attach a existing sqlcipher database(encrypted) in my android application but after copying it in my directory it cannot be opened using \"SQLiteDatabase.openData

相关标签:
2条回答
  • 2021-01-22 20:48

    Are you certain you provided the correct passphrase to the database? Does your database have a configuration (i.e., cipher, page size, kdf iteration length, etc) that differ from the default SQLCipher distribution? I have an example of attaching another SQLCipher database here within the test suite, you might consider running the test suite locally to compare. You might also consider posting this question with your additional details on the SQLCipher mailing list.

    0 讨论(0)
  • 2021-01-22 20:59

    Thanks a lot Nick Parker ,actually i used a code snippet from your sample and i created a new class representing SqlCipherAssestHelper that copy the encrypted DataBase from assets to another location in the device and read/write from the new copy using the database in the sample "1x.db" here

    this is the Helper Calss:

    package com.example.readdbfromas;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import net.sqlcipher.SQLException;
    import net.sqlcipher.database.SQLiteDatabase;
    import net.sqlcipher.database.SQLiteDatabaseHook;
    import net.sqlcipher.database.SQLiteException;
    import net.sqlcipher.database.SQLiteOpenHelper;
    import android.content.Context;
    import android.os.Environment;
    import android.util.Log;
    
    public class DataBaseHelper extends SQLiteOpenHelper {
    
        private static final String DATABASE_NAME = "1x.db";// Encrypted Database
        private static final String SUB_DATABASE_FOLDER = "/DatabaseCipher/";// a sub folder for database location
        public static String DATABASE_PATH;
        public static final int DATABASE_VERSION = 1;
        private SQLiteDatabase myDataBase;
        private final Context context;
        private String password = "";
        private String FULL_DB_Path;
    
        public DataBaseHelper(Context context) {
    
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
    
            DATABASE_PATH = Environment.getExternalStorageDirectory()
                    .getAbsolutePath().toString()
                    + SUB_DATABASE_FOLDER;//get the device root Directory to copy data base on it 
    
            this.context = context;
            SQLiteDatabase.loadLibs(context.getApplicationContext());//load SqlCipher libraries
    
            FULL_DB_Path = DATABASE_PATH + DATABASE_NAME;//full database path
        }
    
        public SQLiteDatabase open(String password) {
            this.password = password;
    
            if (!checkDataBase()) {// if Database Not Exist
                copyDataBase();
            }
    
            myDataBase = getExistDataBaseFile();
    
            return myDataBase;
        }
    
        private SQLiteDatabase getExistDataBaseFile() {// this function to open an Exist database 
    
            SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
                public void preKey(SQLiteDatabase database) {
                }
    
                public void postKey(SQLiteDatabase database) {
                    database.rawExecSQL("PRAGMA cipher_migrate;");
    
                }
            };
            return SQLiteDatabase.openOrCreateDatabase(FULL_DB_Path, password,
                    null, hook);
    
        }
    
    
        private boolean checkDataBase() {// Check database file is already exist or not
            boolean checkDB = false;
            try {
                File dbfile = new File(FULL_DB_Path);
                checkDB = dbfile.exists();
            } catch (SQLiteException e) {
            }
            return checkDB;
        }
    
    
        public void db_delete() {// delete database
            File file = new File(FULL_DB_Path);
            if (file.exists()) {
                file.delete();
                System.out.println("delete database file.");
            }
        }
    
        private void copyDataBase() {//make a sub folder for database location and copy the database
            try {
                File fofo = new File(DATABASE_PATH);
                fofo.mkdirs();
                extractAssetToDatabaseDirectory(DATABASE_NAME);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        public synchronized void closeDataBase() throws SQLException {
            if (myDataBase != null)
                myDataBase.close();
            super.close();
        }
    
        public void extractAssetToDatabaseDirectory(String fileName)
                throws IOException {// copy the database
    
            int length;
            InputStream sourceDatabase = context.getAssets().open(fileName);
            File destinationPath = new File(FULL_DB_Path);
            OutputStream destination = new FileOutputStream(destinationPath);
    
            byte[] buffer = new byte[4096];
            while ((length = sourceDatabase.read(buffer)) > 0) {
                destination.write(buffer, 0, length);
            }
            sourceDatabase.close();
            destination.flush();
            destination.close();
        }
    
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    
        public void onCreate(SQLiteDatabase db) {
        }
    
        public boolean changePassword(String newPassword) {// DataBase must be
                                                            // opened before
                                                            // changing Password
    
            try {
                if (myDataBase != null && myDataBase.isOpen()) {
    
                    myDataBase.rawExecSQL("BEGIN IMMEDIATE TRANSACTION;");
                    myDataBase.rawExecSQL("PRAGMA rekey = '" + newPassword + "';");
    
                    this.close();
                    myDataBase.close();
    
                    return true;
    
                } else {
    
                    Log.e("boolean changePassword()",
                            "Change Password Error : DataBase is null or not opened  !!");
                    return false;
                }
            } catch (Exception e) {
    
                Log.e("boolean changePassword()",
                        "Change Password Error :ExecSQL Error !!");
                return false;
    
            }
    
        }
    
    }
    

    and this code inside activity :

         SQLiteDatabase db;
    DataBaseHelper myDbHelper = new DataBaseHelper(MainActivity.this);
           db=myDbHelper.open("test");
    
    
      Cursor cursor=db.rawQuery("select * from t1", null);
    
    0 讨论(0)
提交回复
热议问题