I am new in Android development. I am making a database through SQLite Manager 0.8.1. The table Users contains two fields, username and password. I created the database file and put it in assets
folder. Now I am trying to read the database from the assets folder. What's the best way to do this? Any help would be appreciated.

- 2,536
- 25
- 57
5 Answers
public class DataBaseHelper extends SQLiteOpenHelper {
private SQLiteDatabase myDataBase;
private final Context myContext;
private static final String DATABASE_NAME = "YOURDBNAME";
public final static String DATABASE_PATH = "/data/data/com.your.packagename/databases/";
public static final int DATABASE_VERSION = 1;
public DataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
}
//Create a empty database on the system
public void createDatabase() throws IOException
{
boolean dbExist = checkDataBase();
if(dbExist)
{
Log.v("DB Exists", "db exists");
// By calling this method here onUpgrade will be called on a
// writeable database, but only if the version number has been
// bumped
//onUpgrade(myDataBase, DATABASE_VERSION_old, DATABASE_VERSION);
}
boolean dbExist1 = checkDataBase();
if(!dbExist1)
{
this.getReadableDatabase();
try
{
this.close();
copyDataBase();
}
catch (IOException e)
{
throw new Error("Error copying database");
}
}
}
//Check database already exist or not
private boolean checkDataBase()
{
boolean checkDB = false;
try
{
String myPath = DATABASE_PATH + DATABASE_NAME;
File dbfile = new File(myPath);
checkDB = dbfile.exists();
}
catch(SQLiteException e)
{
}
return checkDB;
}
//Copies your database from your local assets-folder to the just created empty database in the system folder
private void copyDataBase() throws IOException
{
InputStream mInput = myContext.getAssets().open(DATABASE_NAME);
String outFileName = DATABASE_PATH + DATABASE_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[2024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//delete database
public void db_delete()
{
File file = new File(DATABASE_PATH + DATABASE_NAME);
if(file.exists())
{
file.delete();
System.out.println("delete database file.");
}
}
//Open database
public void openDatabase() throws SQLException
{
String myPath = DATABASE_PATH + DATABASE_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public synchronized void closeDataBase()throws SQLException
{
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion)
{
Log.v("Database Upgrade", "Database version higher than old.");
db_delete();
}
}
}
And to implement it
DataBaseHelper dbhelper = new DataBaseHelper(getApplicationContext());
db = dbhelper.getWritableDatabase();
For that:
Cursor cur;
cur_Herbs = db.rawQuery("select * from TABLENAME where name like '"
+ edit_text_name.gettext.tostring() + "'", null);
if (cur.moveToFirst()) {
do {
int name = cur.getColumnIndex("name");
int pwd= cur.getColumnIndex("pwd");
str_name = cur.getString(name).toString();
str_pwd= cur.getString(ped).toString();
if(str_name.equals(edittext_uname.gettext.tostring()and str_pwd.equals(edittext_pwd.gettext.tostring()))
{
//code for if loginn
}
} while (cur_Herbs.moveToNext());
}

- 7,212
- 7
- 57
- 86

- 8,995
- 9
- 67
- 108
-
thank you sir for reply now i want in my login activity fetch username and password from data base and store in variable and matched with user input how can i do thish and where i use DataBaseHelper dbhelper = new DataBaseHelper(getApplicationContext()); db = dbhelper.getWritableDatabase(); – Mar 25 '14 at 07:38
-
But is this the secure way of copying Files from Assets to Local Store. I mean Linux has a way with permissions, so if in a security review will this effect in any way? – Sri Krishna Oct 15 '15 at 07:49
For those who have a problem to copy db from assets folder in kotlin:
private val DB_PATH = "/data/data/**YOUR_PACKAGE_NAME**/databases/"
private val DB_NAME = "**YOUR_DB_NAME**.db"
private fun copyDataBaseFromAssets(context: Context) {
var myInput: InputStream? = null
var myOutput: OutputStream? = null
try {
val folder = context.getDatabasePath("databases")
if (!folder.exists())
if (folder.mkdirs()) folder.delete()
myInput = context.assets.open("databases/$DB_NAME")
val outFileName = DB_PATH + DB_NAME
val f = File(outFileName)
if (f.exists())
return
myOutput = FileOutputStream(outFileName)
//transfer bytes from the inputfile to the outputfile
val buffer = ByteArray(1024)
var length: Int = myInput.read(buffer)
while (length > 0) {
myOutput!!.write(buffer, 0, length)
length = myInput.read(buffer)
}
//Close the streams
myOutput!!.flush()
myOutput.close()
myInput.close()
} catch (e: IOException) {
e.printStackTrace()
}
}

- 531
- 7
- 15
Use the following:
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}

- 15,750
- 31
- 68
- 83

- 330
- 2
- 10
Kotlin code for doing that, you can find the explanation for each line above the line with a comment, but I'll give a small summary about how it works.
How it gets created
When you create an object from DBHelper
the class will check if the database already copied from the assets
to the device if it's already copied, nothing will happen, but in case of it isn't exist on the device, the database will get copied to the device.
How to use it
You can use it by creating a new instance from DBHelper
then you can call any query method inside, Please check the getQuestions method inside the DBHelper to know how to make a query.
val question = DBHelper(this).getQuestions(currentLevel)
My DB structure for reference
The code:
// Replace this string with your .sql/.db file name
const val dbName = "db_name.db"
// Database version number, you need to change it in case of any schema
// change.
const val dbVersionNumber = 1
class DBHelper(private val context: Context) : SQLiteOpenHelper(context, dbName, null, dbVersionNumber) {
private var dataBase: SQLiteDatabase? = null
init {
// Check if the database already copied to the device.
val dbExist = checkDatabase()
if (dbExist) {
// if already copied then don't do anything.
Log.e("-----", "Database exist")
} else {
// else copy the database to the device.
Log.e("-----", "Database doesn't exist")
createDatabase()
}
}
override fun onCreate(db: SQLiteDatabase?) {
// if you want to do anything after the database created
// like inserting default values you can do it here.
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
// if you want to do anything after the database upgraded
// like migrating values you can do it here.
}
// Copy the database
private fun createDatabase() {
copyDatabase()
}
// Check if the database already copied to the device.
private fun checkDatabase(): Boolean {
val dbFile = File(context.getDatabasePath(dbName).path)
return dbFile.exists()
}
// Copy the database
private fun copyDatabase() {
val inputStream = context.assets.open("dbs/$dbName")
val outputFile = File(context.getDatabasePath(dbName).path)
val outputStream = FileOutputStream(outputFile)
val bytesCopied = inputStream.copyTo(outputStream)
Log.e("bytesCopied", "$bytesCopied")
inputStream.close()
outputStream.flush()
outputStream.close()
}
// Open the database with read and write access mode.
private fun openDatabase() {
dataBase = SQLiteDatabase.openDatabase(context.getDatabasePath(dbName).path, null, SQLiteDatabase.OPEN_READWRITE)
}
// Close the database.
override fun close() {
dataBase?.close()
super.close()
}
// An example of how you can make a query to get one item.
// I have a database with one table called "questions"
// I'm selecting one item at an index I'm passing to the
// method.
// My table has 6 columns: question, choice1, choice2, choice3
// choice4, and correctAnswer.
fun getQuestion(index: Int): Question {
// before you make a query you need to open the database
openDatabase()
// Now you can make a query.
val cursor = dataBase?.rawQuery("select * from questions limit 1 offset $index", null)
// move to first will move the cursor to the first row.
cursor?.moveToFirst()
// now you can get the data from that row
// all my columns is strings so i'm using "getString(index_of_column)"
// but you can also use "getInt(index_of_column)" or any other
// supported type.
val question = cursor?.getString(0) ?: ""
val choice1 = cursor?.getString(1) ?: ""
val choice2 = cursor?.getString(2) ?: ""
val choice3 = cursor?.getString(3) ?: ""
val choice4 = cursor?.getString(4) ?: ""
val correctAnswer = cursor?.getString(5) ?: ""
// After using a cursor you need to close it, so the system can
// release all its resources.
cursor?.close()
// After using the database you need to close it.
close()
return Question(question, choice1, choice2, choice3, choice4, correctAnswer)
}
// An example of how you can make a query to get all the items.
// I have a database with one table called "questions"
// My table has 6 columns: question, choice1, choice2, choice3
// choice4, and correctAnswer.
fun getAllQuestions(): MutableList<Question> {
// before you make a query you need to open the database
openDatabase()
// Now you can make a query.
val cursor = dataBase?.rawQuery("select * from questions", null)
// move to first will move the cursor to the first row.
cursor?.moveToFirst()
val array = mutableListOf<Question>()
do {
// now you can get the data from that row
// all my columns is strings so i'm using "getString(index_of_column)"
// but you can also use "getInt(index_of_column)" or any other
// supported type.
val question = cursor?.getString(0) ?: ""
val choice1 = cursor?.getString(1) ?: ""
val choice2 = cursor?.getString(2) ?: ""
val choice3 = cursor?.getString(3) ?: ""
val choice4 = cursor?.getString(4) ?: ""
val correctAnswer = cursor?.getString(5) ?: ""
// Add the question to the array.
array.add(Question(question, choice1, choice2, choice3, choice4, correctAnswer))
// move to next will move the cursor to the next row if exist.
} while (cursor?.moveToNext() == true)
// After using a cursor you need to close it, so the system can
// release all its resources.
cursor?.close()
// After using the database you need to close it.
close()
return array
}
}

- 2,180
- 1
- 16
- 20
I also use that. I use a default database for my default data. Here is my sample code that works on my applicaiton.
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseHelper extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.test/databases/";
private static String DB_NAME = "testDatabase";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
}
You can use this as reference. Hope this will help you.

- 443
- 6
- 11