I want to ship a SQLite database packed with my app, within Android App Bundle because my app needs it to function. I'm not sure if this is possible at all or app needs to download the data via internet after being installed on Android?
However, if it can be done, I need to know is there a proper path to copy database file, maybe something like 'MyApp\app\src\main\java\com\example\MyApp\databases', I dunno?
Thanx in advance!
You copy the database file into the assets folder(directory) or if you wish the databases folder in the assets folder(directory).
You may need to create the folders. You can do this by right clicking App selecting New/Directory and then selecting or typing src\main\assets (databases after this if you want the databases folder).
You then need to copy the file from the assets (or assets/databases) folder into the location (folder/directory) from which you want to access the database. This is typically data/data/the_package_name/databases which can be ascertained using the Context's getDatabasePath method.
Note that before the copy you should check that the databases folder/directory exists and if not then use the mkdir or mkdirs method(function) to create the directory.
The copy should be done before trying to access the database.
Example
Here's the database in the assets folder:-
using this then here's an example database helper class that extends the SQLiteOpenHelper class, uses a singleton approach, and includes code to:-
Here's the DBHelper class:-
const val DATABASE_NAME = "the_database.db" /* the database name */
const val ASSET_NAME = "the_database.db" /* The name of the asset file which could be different if required */
const val DATABASE_VERSION = 1
const val ASSET_COPY_BUFFER_SIZE = 8 * 1024
class DBHelper: SQLiteOpenHelper {
private constructor(context: Context) : super(context, DATABASE_NAME,null, DATABASE_VERSION)
companion object {
private var instance: DBHelper?=null
fun getInstance(context: Context): DBHelper {
if (this.instance==null) {
getAndCopyAssetDatabase(context)
instance = DBHelper(context);
}
return instance as DBHelper
}
private fun ifDatabaseExists(context: Context): Boolean {
val dbFile = context.getDatabasePath(DATABASE_NAME)
if (dbFile.exists()) return true
else if (!dbFile.parentFile.exists()) {
dbFile.parentFile.mkdirs()
}
return false
}
private fun getAndCopyAssetDatabase(context: Context) {
if (ifDatabaseExists(context)) return
context.assets.open(ASSET_NAME).copyTo(
FileOutputStream(context.getDatabasePath(DATABASE_NAME)),
ASSET_COPY_BUFFER_SIZE
)
}
}
override fun onCreate(p0: SQLiteDatabase?) {
// should not do anything if using a pre-packaged database
}
override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
// May or may not be used
}
}
To use this and force an open/connection to the database then :-
class MainActivity : AppCompatActivity() {
lateinit var db: DBHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = DBHelper.getInstance(this)
db.writableDatabase /* Force Database Access (open) */
}
}
Result (new Install of the App) (via App Inspection):-