Home > front end >  Where in Kotlin Android project folder to copy a SQLite database file?
Where in Kotlin Android project folder to copy a SQLite database file?

Time:10-26

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!

CodePudding user response:

this code below is java:

mydatabase = openOrCreateDatabase("/data/data/your package name 
/files",MODE_PRIVATE,null);

if you are using Kotlin i high recommend you to use Room, which depend on sqlLite but it is cleaner and have more features like return flow of data, and another great features, if you are interested show the below link.

enter image description here

using this then here's an example database helper class that extends the SQLiteOpenHelper class, uses a singleton approach, and includes code to:-

  • see if the database exists as function ifDatabaseExists (which if the database doesn't exist will also create the databases directory if it doesn't exist)
  • get and copy the database from the asset folder as function getAndCopyAssetDatabase (not that this invokes the ifDatabaseExists function).
  • get an instance, the only one i.e. a singleton, of the database helper DBHelper
  • it should noted that getting an instance DOES NOT open/connect to the database (so just getting the instance will not invoke the asset copy)

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):-

enter image description here

  • obviously not your database, just an arbitrary one used to demonstrate.
  • Related