You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite错误码14:Android应用无法打开数据库求助

Fixing SQLite Error Code 14 (Cannot Open Database) in Your Android App

Hey there, let's break down why you're hitting this SQLite error 14—especially since the same code works in another app. Let's start with the most obvious clues from your logs and code.

Key Issue from Logcat

First, look at the critical line in your error log:

open(/data/user/0/com.example.hack.corrector/databases/)

Your app is trying to open the database directory instead of the actual database file (ztr.db) inside that directory. That's why SQLite is throwing error 14—it can't treat a folder as a database.

Problem in Your VocabDatabase Code

The bug is in your checkDataBase() method. Let's look at the problematic line:

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

You're passing DB_PATH (which points to the /databases/ folder) instead of the full path to your database file (DB_PATH + DB_NAME). This causes the open operation to target the directory, not the ztr.db file.

Step-by-Step Fixes

1. Fix the checkDataBase() Method

Update the method to target the actual database file path, and remove the unnecessary getReadableDatabase() call that creates an empty default database:

private boolean checkDataBase() {
    SQLiteDatabase checkDB = null;
    try {
        String myPath = DB_PATH + DB_NAME; // Full path to ztr.db
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); // Use READONLY for check
    } catch (SQLiteException e) {
        // Expected: database doesn't exist yet
        e.printStackTrace();
    }

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

2. Complete the copyDataBase() Method

Your provided code for copyDataBase() is truncated. Here's the full working version to ensure the database is properly copied from assets:

private void copyDataBase() throws IOException {
    // Open local db from assets as input stream
    InputStream myInput = myContext.getAssets().open(DB_NAME);

    // Path to the empty db we created
    String outFileName = DB_PATH + DB_NAME;

    // Open empty db as output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from input to output stream
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Clean up streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
}

3. Ensure the Databases Directory Exists

Add a check to create the /databases/ directory if it doesn't exist in your createDataBase() method:

public void createDataBase() throws IOException {
    boolean dbExist = checkDataBase();
    if (dbExist) {
        return;
    }

    // Create empty database and close it immediately
    SQLiteDatabase emptyDB = this.getWritableDatabase();
    emptyDB.close();

    // Create databases directory if missing
    File dbDir = new File(DB_PATH);
    if (!dbDir.exists()) {
        dbDir.mkdirs();
    }

    try {
        copyDataBase();
    } catch (IOException e) {
        throw new Error("Error copying database: " + e.getMessage());
    }
}

4. Fix Package Name Typos

Notice in your log there's a typo: com.example.hakc.corrector vs your app's package name com.example.hack.corrector. Double-check that all references to the package name in your code (like in class paths and database path logic) are consistent—this mismatch could cause unexpected file access issues.

Why It Works in Another App

The other app likely has the correct database path in its checkDataBase() method, or its package name and directory structure align properly without the path mismatch you have here.

内容的提问来源于stack exchange,提问作者Dante

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:27:45