Shipping the app with a database file is a good idea for me. The advantage is that you don't need to do a complex initialization, which sometimes costs lots of time, if your data set is huge.
Step 1: Prepare database file
Have your database file ready. It can be either a .db file or a .sqlite file. If you use a .sqlite file, all you need to do is to change file extension names. The steps are the same.
In this example, I prepared a file called testDB.db. It has one table and some sample data in it like this
Step 2: Import the file into your project
Create the assets folder if you haven't had one. Then copy and paste the database file into this folder
Step 3: Copy the file to the app's data folder
You need to copy the database file to the app's data folder in order to do further interaction with it. This is a one time action (initialization) to copy the database file. If you call this code multiple times, the database file in data folder will be overwritten by the one in assets folder. This overwrite process is useful when you want to update the database in future during the app update.
Note that during app update, this database file will not be changed in the app's data folder. Only uninstall will delete it.
The database file needs to be copied to /databases
folder. Open Device File Explorer. Enter data/data/<YourAppName>/
location. This is the app's default data folder mentioned above. And by default, the database file will be place in another folder called databases under this directory
Now, the copy file process is pretty much like the what Java is doing. Use the following code to do the copy paste. This is the initiation code. It can also be used to update(by overwriting) the database file in future.
//get context by calling "this" in activity or getActivity() in fragment
//call this if API level is lower than 17 String appDataPath = "/data/data/" + context.getPackageName() + "/databases/"
String appDataPath = context.getApplicationInfo().dataDir;
File dbFolder = new File(appDataPath + "/databases");//Make sure the /databases folder exists
dbFolder.mkdir();//This can be called multiple times.
File dbFilePath = new File(appDataPath + "/databases/testDB.db");
try {
InputStream inputStream = context.getAssets().open("testDB.db");
OutputStream outputStream = new FileOutputStream(dbFilePath);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer))>0)
{
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (IOException e){
//handle
}
Then refresh the folder to verify the copy process
Step 4: Create database open helper
Create a subclass for SQLiteOpenHelper
, with connect, close, path, etc. I named it DatabaseOpenHelper
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseOpenHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "testDB.db";
public static final String DB_SUB_PATH = "/databases/" + DB_NAME;
private static String APP_DATA_PATH = "";
private SQLiteDatabase dataBase;
private final Context context;
public DatabaseOpenHelper(Context context){
super(context, DB_NAME, null, 1);
APP_DATA_PATH = context.getApplicationInfo().dataDir;
this.context = context;
}
public boolean openDataBase() throws SQLException{
String mPath = APP_DATA_PATH + DB_SUB_PATH;
//Note that this method assumes that the db file is already copied in place
dataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.OPEN_READWRITE);
return dataBase != null;
}
@Override
public synchronized void close(){
if(dataBase != null) {dataBase.close();}
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Step 5: Create top level class to interact with the database
This will be the class that read & write your database file. Also there is a sample query to print out the value in the database.
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class Database {
private final Context context;
private SQLiteDatabase database;
private DatabaseOpenHelper dbHelper;
public Database(Context context){
this.context = context;
dbHelper = new DatabaseOpenHelper(context);
}
public Database open() throws SQLException
{
dbHelper.openDataBase();
dbHelper.close();
database = dbHelper.getReadableDatabase();
return this;
}
public void close()
{
dbHelper.close();
}
public void test(){
try{
String query ="SELECT value FROM test1";
Cursor cursor = database.rawQuery(query, null);
if (cursor.moveToFirst()){
do{
String value = cursor.getString(0);
Log.d("db", value);
}while (cursor.moveToNext());
}
cursor.close();
} catch (SQLException e) {
//handle
}
}
}
Step 6: Test running
Test the code by running the following lines of codes.
Database db = new Database(context);
db.open();
db.test();
db.close();
Hit the run button and cheer!