SQLiteException:文件已加密或不是数据库:create locale table failed

时间:2016-01-28 05:33:04

标签: android android-sqlite sqlcipher-android

我有以下两个用于数据库操作的类。

public class BlackboxSQLiteDatabase implements BlackboxDatabase {

    private Context context;
    private SQLiteDatabase sqliteDatabase;
    private String databaseName;
    public static final String IN_MEMORY_DATABASE = null;
    private final String SECRET_KEY = "dm13YXJlY";

    public BlackboxSQLiteDatabase(Context context, String databaseName, int version) {
        this.context = context;
        this.databaseName = databaseName;
        SQLiteDatabase.loadLibs(context);
        SQLiteOpenHelper openHelper = new BlackboxSQLiteOpenHelper(context, databaseName, version);
        this.sqliteDatabase = openHelper.getWritableDatabase(SECRET_KEY);
    }

    @Override
    public void beginTransaction() {
        sqliteDatabase.beginTransaction();
    }

    @Override
    public void setTransactionSuccessful() {
        sqliteDatabase.setTransactionSuccessful();
    }

    @Override
    public void endTransaction() {
        sqliteDatabase.endTransaction();
    }

    @Override
    public int getVersion() {
        return sqliteDatabase.getVersion();
    }

    @Override
    public void execSQL(String statement) {
        sqliteDatabase.execSQL(statement);
    }

    @Override
    public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
        return sqliteDatabase.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
    }

    @Override
    public long insert(String table, String nullColumnHack, ContentValues values) {
        return sqliteDatabase.insert(table, nullColumnHack, values);
    }

    @Override
    public int delete(String table, String whereClause, String[] whereArgs) {
        return sqliteDatabase.delete(table, whereClause, whereArgs);
    }

    @Override
    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
        return sqliteDatabase.update(table, values, whereClause, whereArgs);
    }

    private static final String DROP_TABLE = "DELETE FROM %s ;";
    public void deleteAllData() {
        if (isTestStubDatabase()) {
            return;
        }

        try {
            sqliteDatabase.beginTransaction();
            for (TableSchema tableSchema : BlackboxDatabaseSchema.TABLE_SCHEMAS) {
                String dropCommand = String.format(DROP_TABLE, tableSchema.getTableName());
                sqliteDatabase.execSQL(dropCommand);
            }
            sqliteDatabase.setTransactionSuccessful();
        } finally {
            sqliteDatabase.endTransaction();
        }
    }

    private boolean isTestStubDatabase() {
        return databaseName == IN_MEMORY_DATABASE;
    }

}

public class BlackboxSQLiteOpenHelper extends SQLiteOpenHelper {

    public BlackboxSQLiteOpenHelper(Context context, String name, int version) {
        super(context, name, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        for (TableSchema tableSchema : BlackboxDatabaseSchema.TABLE_SCHEMAS) {
            db.execSQL(tableSchema.getCreateStatement());
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        throw new UnrecoverableException("TODO: implement database upgrade");
    }

}

然后我正在尝试为deleteAllData()方法编写单元测试

public class BlackboxSQLiteDatabaseTests extends InstrumentationTestCase {

    public static final String IN_MEMORY_DATABASE = null;
    private Context context;
    private BlackboxClient blackboxClient;
    private BlackboxDatabase database;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
         /* https://code.google.com/p/dexmaker/issues/detail?id=2
        *  Observing an error on my Nexus 6P without below fix
        *  java.lang.IllegalArgumentException: dexcache == null
        *  (and no default could be found; consider setting the 'dexmaker.dexcache' system property)
        */
        System.setProperty("dexmaker.dexcache",
                getInstrumentation()
                        .getTargetContext()
                        .getCacheDir()
                        .getPath());
        context = getInstrumentation().getTargetContext();
        database = new BlackboxSQLiteDatabase(context, "config.db", 1);

    }

    public void testDeleteAllData() {
        //test code
     }

}

然后在运行单元测试时出现此错误。

net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: create locale table failed
at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2474)
at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2338)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1087)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1150)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:129)
at com.mc.gc.storage.BlackboxSQLiteDatabase.<init>(BlackboxSQLiteDatabase.java:35)
at com.mc.gc.storage.BlackboxSQLiteDatabaseTests.setUp(BlackboxSQLiteDatabaseTests.java:44)

我肯定每次使用相同的密钥来打开数据库,作为常量。有人可以指出这里可能存在的问题。每次运行测试代码时都会出现相同的错误。

1 个答案:

答案 0 :(得分:0)

我在设备中有一个过时的应用程序副本导致了这个问题。我卸载并删除所有旧副本,测试似乎正在运行。对不起,麻烦的家伙们。