gpt4 book ai didi

android - Sqlcipher __ CREATE TABLE android_metadata 失败

转载 作者:太空狗 更新时间:2023-10-29 15:46:35 26 4
gpt4 key购买 nike

我正在尝试在我的 android 应用程序中附加一个现有的 sqlcipher 数据库(已加密),但是在将其复制到我的目录后,它无法使用“SQLiteDatabase.openDatabase(...)”打开

我在普通的 sqlite 中尝试了代码并且它工作正常但是当我使用 sqlcipher API 时我收到了这个错误消息

 //CREATE TABLE android_metadata failed
//Failed to setLocale() when constructing, closing the database
// net.sqlcipher.database.SQLiteException: file is encrypted or is not a database

我在 SQLiteOpenHelper 类中使用了以下代码:

      if(!dbExist1)
{

this.getWritableDatabase(password);
this.openDatabase();
try
{
this.close();
copyDataBase();
}
catch (IOException e)
{

throw new Error("Error copying database");
}
}


public SQLiteDatabase openDatabase() throws SQLException {
String DBPath = DATABASE_PATH + DATABASE_NAME;

myDataBase = SQLiteDatabase.openDatabase(DBPath, password, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDataBase;
}

我在 Activity 类中使​​用了以下代码:

  SQLiteDatabase.loadLibs(this);
DataBaseHelper myDbHelper ;
myDbHelper = new DataBaseHelper(this);
SQLiteDatabase db=myDbHelper.openDatabase();

我尝试使用 this solution但还是一样的错误

Blockquote

最佳答案

非常感谢 Nick Parker,实际上我使用了您示例中的代码 fragment ,并且我创建了一个代表 SqlCipherAssestHelper 的新类,它将加密的数据库从 Assets 复制到设备中的另一个位置,并使用数据库从新副本读取/写入在样本“1x.db”中 here

这是助手调用:

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;

}

}

}

Activity 中的这段代码:

     SQLiteDatabase db;
DataBaseHelper myDbHelper = new DataBaseHelper(MainActivity.this);
db=myDbHelper.open("test");


Cursor cursor=db.rawQuery("select * from t1", null);

关于android - Sqlcipher __ CREATE TABLE android_metadata 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20373066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com