Sqlcipher __ Create Table Android_metadata Failed
Solution 1:
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;
publicclassDataBaseHelperextendsSQLiteOpenHelper {
privatestaticfinalStringDATABASE_NAME="1x.db";// Encrypted DatabaseprivatestaticfinalStringSUB_DATABASE_FOLDER="/DatabaseCipher/";// a sub folder for database locationpublicstatic String DATABASE_PATH;
publicstaticfinalintDATABASE_VERSION=1;
private SQLiteDatabase myDataBase;
privatefinal Context context;
privateStringpassword="";
private String FULL_DB_Path;
publicDataBaseHelper(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 SQLiteDatabaseHookhook=newSQLiteDatabaseHook() {
publicvoidpreKey(SQLiteDatabase database) {
}
publicvoidpostKey(SQLiteDatabase database) {
database.rawExecSQL("PRAGMA cipher_migrate;");
}
};
return SQLiteDatabase.openOrCreateDatabase(FULL_DB_Path, password,
null, hook);
}
privatebooleancheckDataBase() {// Check database file is already exist or notbooleancheckDB=false;
try {
Filedbfile=newFile(FULL_DB_Path);
checkDB = dbfile.exists();
} catch (SQLiteException e) {
}
return checkDB;
}
publicvoiddb_delete() {// delete databaseFilefile=newFile(FULL_DB_Path);
if (file.exists()) {
file.delete();
System.out.println("delete database file.");
}
}
privatevoidcopyDataBase() {//make a sub folder for database location and copy the databasetry {
Filefofo=newFile(DATABASE_PATH);
fofo.mkdirs();
extractAssetToDatabaseDirectory(DATABASE_NAME);
} catch (IOException e) {
e.printStackTrace();
}
}
publicsynchronizedvoidcloseDataBase()throws SQLException {
if (myDataBase != null)
myDataBase.close();
super.close();
}
publicvoidextractAssetToDatabaseDirectory(String fileName)throws IOException {// copy the databaseint length;
InputStreamsourceDatabase= context.getAssets().open(fileName);
FiledestinationPath=newFile(FULL_DB_Path);
OutputStreamdestination=newFileOutputStream(destinationPath);
byte[] buffer = newbyte[4096];
while ((length = sourceDatabase.read(buffer)) > 0) {
destination.write(buffer, 0, length);
}
sourceDatabase.close();
destination.flush();
destination.close();
}
publicvoidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
publicvoidonCreate(SQLiteDatabase db) {
}
publicbooleanchangePassword(String newPassword) {// DataBase must be// opened before// changing Passwordtry {
if (myDataBase != null && myDataBase.isOpen()) {
myDataBase.rawExecSQL("BEGIN IMMEDIATE TRANSACTION;");
myDataBase.rawExecSQL("PRAGMA rekey = '" + newPassword + "';");
this.close();
myDataBase.close();
returntrue;
} else {
Log.e("boolean changePassword()",
"Change Password Error : DataBase is null or not opened !!");
returnfalse;
}
} catch (Exception e) {
Log.e("boolean changePassword()",
"Change Password Error :ExecSQL Error !!");
returnfalse;
}
}
}
and this code inside activity :
SQLiteDatabase db;
DataBaseHelpermyDbHelper=newDataBaseHelper(MainActivity.this);
db=myDbHelper.open("test");
Cursor cursor=db.rawQuery("select * from t1", null);
Solution 2:
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.
Post a Comment for "Sqlcipher __ Create Table Android_metadata Failed"