1

I've checked at all the solutions, but I keep getting the error.

The database exists, and I could use the same database before with the same code, but now I'm getting this error. I need help from those who have received the same error before.

Thank you..

error image = https://ibb.co/GxBFznf

my DbHelper class;

public DbHelper(@Nullable Context context) {

    super(context, DB_NAME, null, 1);

    assert context != null;
    DB_PATH = context.getApplicationInfo().dataDir + "/databases/";

    openDataBase(); 
    this.mContext = context;

}


public void openDataBase() {

    String myPath = DB_PATH + DB_NAME;
    mDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

}

public void copyDataBase() throws IOException {

    try {
        InputStream myInput = mContext.getAssets().open(DB_NAME);
        String outputFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outputFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0)
            myOutput.write(buffer, 0, length);

        myOutput.flush();
        myOutput.close();
        myInput.close();
        ;
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public boolean checkDataBase() {

   SQLiteDatabase tempDB = null;

    try {
        String myPath = DB_PATH + DB_NAME;
        File file = new File(myPath);
        if(file.exists() && !file.isDirectory())
        tempDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

    } catch (SQLException e) {
        e.printStackTrace();
    }

    if (tempDB != null)
        tempDB.close();

    return tempDB != null ? true : false;
}

public void createDataBase() throws IOException {

    boolean isDBExist = checkDataBase();
    if (isDBExist) {

    } else {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

my MainActivity;

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    seekBar = (SeekBar)findViewById(R.id.seekBar);
    txtMode= (TextView) findViewById(R.id.txtMode);
    btnPlay = (Button)findViewById(R.id.btnPlay);
    btnScore = (Button)findViewById(R.id.btnScore);

    db = new DbHelper(this);
    try{
        db.createDataBase();
    }
    catch (IOException e){
        e.printStackTrace();
    }
MikeT
  • 51,415
  • 16
  • 49
  • 68
Efe
  • 53
  • 6
  • Does this answer your question? [Failed to open Database Android Java SQLite](https://stackoverflow.com/questions/28386373/failed-to-open-database-android-java-sqlite) – Matt U Dec 09 '19 at 15:50
  • @MattU Unfortunately it doesnt, i have tried and keep getting same error – Efe Dec 09 '19 at 15:59

1 Answers1

0

When you instantiate DbHelper as in db = new DbHelper(this); the constructor tries to open the database when it does not exist.

public DbHelper(@Nullable Context context) {

    super(context, DB_NAME, null, 1);

    assert context != null;
    DB_PATH = context.getApplicationInfo().dataDir + "/databases/";

    openDataBase(); //<<<<<<<<<< WILL ONLY WORK IF DB EXISTS
    this.mContext = context;

}

You could instead use :-

public DbHelper(@Nullable Context context) {

    super(context, DB_NAME, null, 1);
    assert context != null;
    this.mContext = context;
    DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
    if (!checkDataBase()) {
        try {
            createDataBase();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Unable to Copy Database");
        }
    }
    openDataBase();        
}

In which case MainActivity could be :-

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    seekBar = (SeekBar)findViewById(R.id.seekBar);
    txtMode= (TextView) findViewById(R.id.txtMode);
    btnPlay = (Button)findViewById(R.id.btnPlay);
    btnScore = (Button)findViewById(R.id.btnScore);

    db = new DbHelper(this);
}
MikeT
  • 51,415
  • 16
  • 49
  • 68
  • yes it worked, thank you so much my friend. but I have db, so db is exist, why am I getting error. – Efe Dec 09 '19 at 20:41
  • @Efe The database does not exist until it is copied from the assets, you were trying to open it before it had been copied. – MikeT Dec 09 '19 at 20:58
  • Yeah understood i get it, you're right. Thank you again – Efe Dec 09 '19 at 21:18
  • if I run API 27, 28 or 29, I get the same error again :( – Efe Dec 14 '19 at 21:09
  • @Efe that is probably because of you are using `this.getReadableDatabase();`. Which creates a database and post Android 9 the default database mode was changed from jounal to WAL. see [answer here](https://stackoverflow.com/questions/55336900/a-pre-populated-database-does-not-work-at-api-28-throws-no-such-table-exceptio/55346290#55346290) – MikeT Dec 14 '19 at 21:17
  • MikeT, after doing this, i getting this error; E/AndroidRuntime: FATAL EXCEPTION: main Process: maina.ctivity, PID: 25081 java.lang.RuntimeException: Unable to start activity ComponentInfo{maina.ctivity/maina.ctivity.MainActivity}: java.lang.RuntimeException: Error copying database – Efe Dec 15 '19 at 13:46