Search code examples
javaandroidandroid-sqlitesqlexception

How to specify the path to the database created in the class inherited from SQLiteOpenHelper in the method?


There is a method taken from https://metanit.com/java/android/14.4.php:

public SQLiteDatabase open()throws SQLException {
 
    return SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
}

The problem is that in this example, the database is created explicitly in the assets folder

But in my case, the database is created in the class:

public class PreparationDBHelper extends SQLiteOpenHelper {

    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "PreparationDb";
    public static final String TABLE_TEXT = "textTable";

    public static final String KEY_ID = "_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_TEXT = "text";

    public PreparationDBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table " + TABLE_TEXT + "(" + KEY_ID
                + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + KEY_NAME + " text," + KEY_TEXT + " text" + ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists " + TABLE_TEXT);

        onCreate(db);
    }

/*    public SQLiteDatabase open()throws SQLException {

        return SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
    }*/
}

How do I specify the path to the database in the open () method in my case?


Solution

  • How do I specify the path to the database in the open () method in my case?

    You don't need to have an open() method and probably shouldn't. Rather from an instance of the PreparationDBHelper class, you use either the getWritableDatabase() or the getReadableDatabase() method to get an opened SQLiteDatabase.

    • getReabaleDatabase will in most situations return a writable database, it DOES NOT protect the database against being updated.

    • PreparationDBHelper extends SQliteOpenHelper so named as it helps you to open the database. Hence there is little need to otherwise open the database.

      • Note that the database will not be opened until either one of the get????ableDatabase methods is called.
    • If you really want the path then in your case you can use your_context.getDatabasePath(DATABASE_NAME) (your_context being a Context) which returns a File object from which you can retrieve the path as a string e.g. String myDBPath = your_context.getDatabasePath(DATABASE_NAME).getPath() (see File as there are also getAbsolutePath and getCanonicalPath methods).

      • However, this assumes that the database is stored at the recommended location (as it will be in your case, but you can store the database elsewhere); you can alternately, you can use the SQLiteDatabase's (returned from getWritableDatabase and getReadableDatabase) getPath() method.
    • In the example code you have pointed to DB_PATH =context.getFilesDir().getPath() + DB_NAME; is used (this will place the database at data/data/<package_name>/ rather than at the recommended data/data/<package_name>/databases/). Really the example should have used DB_PATH = context.getDatabasePath(DB_NAME).getPath();

    The problem is that in this example, the database is created explicitly in the assets folder.

    It is not, the database is copied (if the database doesn't already exist) from the assets folder to it's final location (which is not the recommended location).

    • It would appear that rather than use the recommended location for the database, the example has circumvented handling the issue that the databases folder doesn't exist when an application is installed and that the copy will fail, if using the recommended location, unless the databases directory is created. All that would have been required is a single extra line file.mkdirs().