Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 tryed 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 everytime 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 stackoverflow 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();
    }
}
like image 721
NullPointerException Avatar asked Oct 08 '18 16:10

NullPointerException


2 Answers

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();
    }
}
like image 179
NullPointerException Avatar answered Sep 20 '22 23:09

NullPointerException


In your DBHelper class, you are creating the DB before you testing the if DB exists in method Util.getDatabasePath(DB_NAME). This line creating the DB

this.DB_COMPLETE_PATH = Util.getDatabasePath(DB_NAME);

By calling this method You sql open helper creates the databse(in your case empty because in OnCreate() method notthing happens).

If you are storing your DB in default app's db path then you can check if DB exist by next snippet:

File f = context.getDatabasePath("my_database.db");
if(f.exists()) {
   //Your code if DB exist
} else {
   //Your code if DB doesn't exist
}

And the better place to disable WAL is onConfigure() method in SQLiteOpenHelper

like image 24
LifeStyle Avatar answered Sep 19 '22 23:09

LifeStyle