无法在Android Pie(Android 9)中打开数据库。

6

我曾使用checkDataBase函数来确保数据库已经存在,以避免在Oreo中每次打开应用程序时重新复制文件。但在Android Pie中,它不起作用。

private boolean checkDataBase (String dbName, int dbVersion) {

    SQLiteDatabase checkDB = null;

    try {

        String myPath = DB_PATH + dbName;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.CONFLICT_ABORT);

        if (checkDB.getVersion() < dbVersion) {
            Timber.d("Delete database called");
            myContext.deleteDatabase(dbName);
            return false;
        }
    } catch(SQLiteException e) {

    }

    if(checkDB != null){
        checkDB.close();
    }

    return checkDB != null;
}

遇到这个错误:os_unix.c:36667: (2) open(/data/data/my.androidPieTrial.app/databases/admin.db),android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14 SQLITE_CANTOPEN): Could not open database。
3个回答

12

我找到了解决方案。在 Android Oreo 及以下版本中,我访问数据库的方式运作良好,但在 Android Pie 中无效。这是在 Android Pie 中处理它的方法。

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        MySQLiteOpenHelper helper = new MySQLiteOpenHelper();
        SQLiteDatabase database = helper.getReadableDatabase();
        myPath = database.getPath();

    } else {
        String DB_PATH = Environment.getDataDirectory() + "/data/my.trial.app/databases/";
        myPath = DB_PATH + dbName;
    }

    checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    checkDB.disableWriteAheadLogging();

我有同样的问题,你能帮我解决这个问题吗? 我无法理解你在这段代码片段中所说的话, 你能请再详细解释一下吗? - Developers Park
1
@APOORVADOSHI 基本上,不是使用基于 Environment.getDataDirectory 的硬编码路径来获取 Pie 版本的路径,而是使用了一种改进的方法(通过系统获取路径)。然而,真正正确的方法是使用 context.getDatabasePath(the_database_name).getAbsolutePath();(自 API 1 起可用,因此适用于所有版本)。 - MikeT
3
我也遇到了同样的问题。请问您能否分享MySQLiteOpenHelper类,否则很难理解如何解决这个问题。 - Faisal
1
这对我很有用,但重要的部分是使用:checkDB.disableWriteAheadLogging(); - u2tall
我也遇到了同样的问题,但对我没有起作用。 - Tanveer Ahmed
我正在使用SQLiteAssetHelper,在第一次尝试打开数据库时遇到了NullPointerException。 数据库没有从资产文件夹复制。 - Ankit Sahu

4

在Android Pie操作系统版本上,覆盖SQLiteOpenHelper类的以下方法。

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        db.disableWriteAheadLogging();
    }
}

3
context.getDatabasePath(the_database_name).getPath();

getDatabasePath() 方法返回创建数据库时在文件系统上的绝对路径,因此可以正常工作。适用于所有版本的 Android。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接