Copy Database from Assets Folder in Unrooted Device

Copy Database from assets folder in unrooted device

This will work for sure in all devices and emulator, no need to root.

/**
* 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(String dbname) throws IOException {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(dbname);
// Path to the just created empty db
File outFileName = myContext.getDatabasePath(dbname);
// 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();
}

Android: Copying Database From Asset Folder

Try below code and let me know whether is it working properly?

 public class DataBaseWrapper extends SQLiteOpenHelper
{
private static String TAG = DataBaseWrapper.class.getName();
private String DB_PATH; //= "/data/data/com.example.yourproject/databases/";
private static String DB_NAME = "Database.sqlite";
private SQLiteDatabase myDataBase = null;
private final Context myContext;

public DataBaseWrapper(Context context)
{
super(context, DB_NAME, null, 1);

this.myContext = context;
DB_PATH="/data/data/" + context.getPackageName() + "/" + "databases/";
Log.v("log_tag", "DBPath: " + DB_PATH);
// File f=getDatabasePath(DB_NAME);
}

public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
Log.v("log_tag", "database does exist");
}else{
Log.v("log_tag", "database does not exist");
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}

private void copyDataBase() throws IOException{
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}

private boolean checkDataBase(){

File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();

}

public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
myDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDataBase != null;

}


@Override
public synchronized void close()
{
if(myDataBase != null)
myDataBase.close();
super.close();
}

@Override
public void onCreate(SQLiteDatabase db)
{


}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.v(TAG, "Upgrading database, this will drop database and recreate.");
}
}

copy database from assets to databases folder

My method

Get Your Database path using the following

ContextWrapper cw =new ContextWrapper(getApplicationContext());
DB_PATH =cw.getFilesDir().getAbsolutePath()+ "/databases/"; //edited to databases

Then you can go this way

private void copyDataBase()
{
Log.i("Database",
"New database is being copied to device!");
byte[] buffer = new byte[1024];
OutputStream myOutput = null;
int length;
// Open your local db as the input stream
InputStream myInput = null;
try
{
myInput =myContext.getAssets().open(DB_NAME);
// transfer bytes from the inputfile to the
// outputfile
myOutput =new FileOutputStream(DB_PATH+ DB_NAME);
while((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
myOutput.close();
myOutput.flush();
myInput.close();
Log.i("Database",
"New database has been copied to device!");


}
catch(IOException e)
{
e.printStackTrace();
}
}

Copy SQlite DB to public directory (non rooted devices)


I changed the constructor like this:

Problem is that in constructor you're specifing only database name and not path. Database created by SQLiteOpenHelper will be placed always in internal storage for security reasons - you can't change this logic. It's build-in logic by OS.

All what you can do is explicitly copy your database into another directory.

In this thread you'll find how to copy database.

Update:

Here is how to get database path:

String path = getApplicationContext().getDatabasePath("your_database_name");

Unable to copy SQLite database from assests folder to device memory

EDIT: Replace your code with this and let me know what happen, (This works fine in my case..)

DbManager.java class:

public class DbManager {
private DatabaseHelper dataHelper;
private SQLiteDatabase mDb;
Context ctx;
String DATABASE_PATH = "/data/data/com.demo/databases/";
static String DATABASE_NAME="AndroidDB";

private static final int DATABASE_VERSION = 1;
DbManager(Context ctx)
{
this.ctx = ctx;
dataHelper = new DatabaseHelper(ctx);

}

private static class DatabaseHelper extends SQLiteOpenHelper {

Context myContext = null;

public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
// TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

Log.w("DBHelper", "Upgrading database from version "
+ oldVersion + " to " + newVersion
+ ", which will destroy all old data");

onCreate(db);

}

}


public boolean checkDataBase() {

String myPath = DATABASE_PATH + DATABASE_NAME;
File f = new File(myPath);
return f.exists();
}

public void createDataBase() {

openDB();
try {
InputStream myInput = ctx.getAssets().open("AndroidDB.db");
OutputStream myOutput = new FileOutputStream(DATABASE_PATH
+ "AndroidDB");

byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}

if (mDb.isOpen())
mDb.close();
myOutput.flush();
myOutput.close();
myInput.close();

} catch (FileNotFoundException e) {
throw new Error("file not found -- " + e.getMessage());
} catch (IOException e) {
throw new Error("io exception " + e.getMessage());
} catch (Exception e) {
throw new Error(" exception " + e.getMessage());
}
}

public DbManager openDB() throws SQLException {

mDb = dataHelper.getWritableDatabase();
return this;
}

public String[] getSymbol() {
Cursor cur;
try {
cur = mDb.rawQuery("select symbol,company_name from Scrip", null);
} catch (SQLiteException e) {
throw new Error(" *** ERROR in cursor *** " + e.getMessage());
}

String[] b1 = new String[1326];
int x = 0;
if (cur.moveToFirst()) {
do {
b1[x] = cur.getString(cur.getColumnIndex("symbol"));
x++;
} while (cur.moveToNext());
}
cur.close();
return b1;
}

public void close() {
try {
mDb.close();
} catch (Exception e) {
e.printStackTrace();
}

}

}

Can SQLite file copied successfully on the data folder of an unrooted android device ?

I assume that your DB_NAME is not the same to the Database which exists in your assests folder.

If you are following reigndesign, then check this line:

private static String DB_NAME ="myDBName";  

DB_NAME here is the name of your database. It is assumed that you have a copy of the database in the assets folder. Your DB_NAME must be the same which exists in the assets folder.

OR

Follow this.

Reading from assets directs to wrong path?

First of all
You need to create a database in the destination. After that you can copy of top of it.

So. this is what i use.

I created a class Database that extends from SQLiteOpenHelper

In this class i do the following.

// Database Version
private static final int DB_VERSION = 1;

// Database Name
private static String DB_NAME = "DB.sqlite";

//The default system path of your application database.
private static String DB_PATH = "/data/data/com.namespace.xxx/databases/";

public Database(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
}

public void createDataBase() throws IOException{

Log.d(LOG, "Calling checkDataBase() Method");

boolean dbExist = checkDataBase();

if(dbExist){
//do nothing - database already exist
Log.d(LOG, "!!!Database Found!!!");
}else{
//Empty database will be created into the default system path
Log.d(LOG, "!!!Creating Empy Database!!!");
this.getReadableDatabase();
this.close();
try {
Log.d(LOG, "!!!Coping Database!!!");
copyDataBase();
} catch (IOException e) {
throw new Error(e);
}
}
}

private boolean checkDataBase(){

SQLiteDatabase checkDB = null;

try{
String myPath = DB_PATH + DB_NAME;

Log.d(LOG, "looking database at " + myPath);

checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

}catch(SQLiteException e){
//database does't exist yet.
Log.e(LOG, "Exception: database does not exist yet");
}

if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}

// Copies your database from your local assets-folder
// to the created empty database
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;

Log.d(LOG, "Coping database from " + myInput + ", to " + outFileName);

//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();
}

Good Luck.

What is the default database location of an android app for an unrooted device?? Is it same as for rooted one?

Yeah, For both the cases it will be same path. /data/data/<application_package_name>/databases

Now, on un-rooted device you can not access /data/ directory of device's internal storage. That's why you can not seen the database file.

If you want to get the file you can copy database file from internal storage /data/data/<application_package_name>/databases to external storage (sdcard) then using ddms or adb pull get the database file.

Also just try command adb pull /data/data/<application_package_name>/databases/<database_file_name> from your system to get the database file.

But by default all the android application store database on internal storage path /data/data/<application_package_name>/databases. And its applicable for all devices rooted or un-rooted.



Related Topics



Leave a reply



Submit