android - 拦截数据库错误 "file is encrypted or is not a database"

标签 android database sqlite

因为我正在尝试实现导入/导出数据,所以我想测试如果导入的文件不是 sqlite 数据库会发生什么来管理错误。

在 logcat 中我有以下内容:

03-22 15:02:39.957: E/SQLiteLog(20407): (26) file is encrypted or is not a database
03-22 15:02:39.978: E/DefaultDatabaseErrorHandler(20407): Corruption reported by sqlite on database: /data/data/com.crbin1.ltd/databases/dbltd
03-22 15:02:40.017: E/DefaultDatabaseErrorHandler(20407): deleting the database file: /data/data/com.crbin1.ltd/databases/dbltd

应用程序只需为用户创建一个新的空数据库,不会出错。

在数据库导入之后我调用了下面的代码(DatabaseLTD 是我的 SQliteOpenHelper 类)

private void checkImportedDb() {
    try {
        DatabaseLTD dbltd = new DatabaseLTD(mCtx);
        SQLiteDatabase db = dbltd.getReadableDatabase();
    } catch (SQLiteException e) {
        e.printStackTrace();
    }
}

但我无法拦截“文件已加密或不是数据库”错误。我怎样才能捕捉到错误来管理它?

最佳答案

SQLiteOpenHelper 构造函数:

public SQLiteOpenHelper (Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler)

需要一个错误处理程序参数“DatabaseErrorHandler”。

to be used when sqlite reports database corruption, or null to use the default error handler.

这可能是您正在寻找的。

编辑:正如 crbin1 正确指出的那样,构造函数仅是 API >= 11。

对于 API < 11,我(未经测试)的建议是打开数据库并获取表列表:

Retrieve a list of all tables in the database

如果您应该加载的数据库必须至少有一个,您可以检查该数字,或者更好的是,确保一个特定的表已经存在。

如果您也希望能够检查空数据库,作为最后的努力,您可以尝试 SQLiteDatabase 方法:

public static SQLiteDatabase openDatabase (String path, SQLiteDatabase.CursorFactory factory, int flags) 

我没有检查,但我强烈怀疑此方法的文档不正确,因为有关“flag”参数的信息不一致,特别是行:

Open the database according to the flags OPEN_READWRITE OPEN_READONLY CREATE_IF_NECESSARY and/or NO_LOCALIZED_COLLATORS.

与“int flags”参数的存在冲突:

flags to control database access mode

我知道我是个懒鬼,我应该自己检查一下,但是如果是这样的话,您可以尝试使用 openDatabase 预先验证数据库,使用 OPEN_READONLY 并且没有 CREATE_IF_NECESSARY,捕获异常(如果有) ,然后继续使用“标准”SQLiteOpenHelper 方法。

关于android - 拦截数据库错误 "file is encrypted or is not a database",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15573771/

相关文章:

java - NetworkInfo.isConnected() 和 NetworkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED 之间的区别。用什么?

mysql - Laravel5 帮助构建查询语法

SQLite 时间戳字段 - 转换为日期时间

SQLite:使用单独的行搜索关键字表并连接多个表

node.js - node-sqlite 插入在非空约束上失败,但数据在那里?

java - 获取设备中的内部可用存储空间

java - 蓝牙回调函数 onCharacteristicRead 没有对使用 <API 21 的另一个 Activity 进行 Intent 调用。不在 Marshmallow 中

android - 设计 UI Android(CardViews 之间的元素)

sql - 无论如何通过配置单元(HQL)将行值转换为列键?

.net - .Net 中 Oracle DataReader 的大性能问题