SQLite错误码14:Android应用无法打开数据库求助
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

