androidsqliteandroid-sqliteandroid-databaseandroid-9.0-pie

SQLite: No Such Table Error Android P problem


Until Android P everything worked fine with my code but now in Android P I'm having a lot of problems working with databases.

I have .db SQLite database files stored on assets folder. I was importing them into the database space of Android and it worked fine until Android P. In android P I'm getting this exception: SQLite: No Such Table Error

I searched here and found this, and I tried to apply the accepted answer: Android P - 'SQLite: No Such Table Error' after copying database from assets

The problem is that now I'm having another problem and It still doesn't works. Now I'm having the problem that every time I try to check if the database already exists, this code always returns true, so I never create the database. Even with the database not created, even with the app recently installed:

private boolean checkIfDBExists() {
    File dbFile = new File(DB_COMPLETE_PATH);
    return dbFile.exists();
}

My source code is the source code of the accepted answer in the previously quoted Stack Overflow question.

The new Android P required way of getting the DB path:

public static String getDatabasePath(String fileNname){
    MySQLiteOpenHelper helper = new MySQLiteOpenHelper(ApplicationContextProvider.getContext(), fileNname);
    SQLiteDatabase database = helper.getReadableDatabase();
    String path = database.getPath();
    database.close();
    return path;
}

public class MySQLiteOpenHelper extends SQLiteOpenHelper {
    public MySQLiteOpenHelper(Context context, String databaseName) {
        super(context, databaseName, null, 2);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        db.disableWriteAheadLogging();
    }
}

My DBHelper class:

public class DbHelper extends SQLiteOpenHelper{ 
    private  String DB_NAME;
    private  String DB_COMPLETE_PATH;
    private SQLiteDatabase mDataBase;
    private static final int DATABASE_VERSION = 1;
    
    public DbHelper(String name) throws IOException {
        super(ApplicationContextProvider.getContext(), name+".db", null, DATABASE_VERSION);
        this.DB_NAME = name+".db";
        this.DB_COMPLETE_PATH = Util.getDatabasePath(DB_NAME);

        boolean mustOverWriteDB; 
        
        if (checkIfDBExists()==false) {
            createDataBase();
        }
        
        openDataBase();
    }

    private void createDataBase() throws IOException {
        this.getReadableDatabase();
        try {           
            copyDataBase();            
        } catch (IOException e) {           
            throw new RuntimeException(e);
        }
    }

    public void copyDataBase() throws IOException {
        InputStream myInput = App.getInstance().getAssetsFile(DB_NAME);
        String outFileName = DB_COMPLETE_PATH;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }
}

Solution

  • Arg finally solved it adding this.close(); after this.getReadableDatabase();

    That openned connection was generating the original no such table exception

    So I used Util.getDatabasePath(DB_NAME); instead of the complex propossed solution in Android P - 'SQLite: No Such Table Error' after copying database from assets and now the code is much more simpler

    Thanks a lot to @LifeStyle who found the real problem.

    Now the code is much more simpler:

    public static String getDatabasePath(String fileNname){
        return ApplicationContextProvider.getContext().getDatabasePath(fileNname).getAbsolutePath();
    }
    
    public class DbHelper extends SQLiteOpenHelper{
        private String DB_NAME;
        private String DB_COMPLETE_PATH;
        private SQLiteDatabase mDataBase;
        private static final int DATABASE_VERSION = 1;
    
        public DbHelper(String name) throws IOException {
            super(ApplicationContextProvider.getContext(), name+".db", null, DATABASE_VERSION);
            this.DB_NAME = name+".db";
            this.DB_COMPLETE_PATH = Util.getDatabasePath(DB_NAME);
    
            if (checkIfDBExists()==false){
                createDataBase();
            }
    
            openDataBase();
        }
    
        private void createDataBase() throws IOException {
            this.getReadableDatabase();
            this.close();
            try {           
                copyDataBase();            
            } catch (IOException e) {           
                throw new RuntimeException(e);
            }
        }
    
        private boolean checkIfDBExists() {
            File dbFile = new File(DB_COMPLETE_PATH);
            return dbFile.exists();
        }
    }