Copy Database from Assets to Databases Folder

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 database from assets folder

Change your while loop as below:

Besides your condition >= greater than or equal to change it to only > Greater than

while ((length = myInput.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}

Try out the below code which will work for you like charm.

public class DataBaseHelper extends SQLiteOpenHelper {
private Context mycontext;
private String DB_PATH;

private static String DB_NAME = "abc.sqlite";
public SQLiteDatabase myDataBase;

public DataBaseHelper(Context context) throws IOException {
super(context,DB_NAME,null,1);
this.mycontext=context;
boolean dbexist = checkdatabase();
if (dbexist) {
opendatabase();
} else {
System.out.println("Database doesn't exist");
createdatabase();
}
}

public void createdatabase() throws IOException {
boolean dbexist = checkdatabase();
if(!dbexist) {
this.getReadableDatabase();
try {
copydatabase();
} catch(IOException e) {
throw new Error("Error copying database");
}
}
}

private boolean checkdatabase() {

boolean checkdb = false;
try {
String myPath = DB_PATH + DB_NAME;
File dbfile = new File(myPath);
checkdb = dbfile.exists();
} catch(SQLiteException e) {
System.out.println("Database doesn't exist");
}
return checkdb;
}

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 byte to inputfile to 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_READWRITE);
}

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

}

In your MainActivity you just now need to create and instance of your DatabaseHelper class others will managed on it own.

public class MainActivity extends Activity {
DatabaseHelper myDbHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.layout);
myDbHelper = new DatabaseHelper(MainActivity.this);
}

}

How to copy database from assets folder in android using kotlin

Add this class for copy a database from assets in Kotlin:

class AssetDatabaseOpenHelper(private val context: Context) {

companion object {

private val DB_NAME = "asset_db_name.db"
}

fun openDatabase(): SQLiteDatabase {
val dbFile = context.getDatabasePath(DB_NAME)

if (!dbFile.exists()) {
try {
val checkDB = context.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE,null)

checkDB?.close()
copyDatabase(dbFile)
} catch (e: IOException) {
throw RuntimeException("Error creating source database", e)
}

}
return SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READWRITE)
}

@SuppressLint("WrongConstant")
private fun copyDatabase(dbFile: File) {
val `is` = context.assets.open(DB_NAME)
val os = FileOutputStream(dbFile)

val buffer = ByteArray(1024)
while (`is`.read(buffer) > 0) {
os.write(buffer)
Log.d("#DB", "writing>>")
}

os.flush()
os.close()
`is`.close()
Log.d("#DB", "completed..")
}

}

And than open or create database from your activity using

val adb = AssetDatabaseOpenHelper(this)

adb.openDatabase()

Log.d("#DB","writing>>"); will show you database entries in Logcat.

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 folder to android , updating it and copying it back to asset folder

As the assets folder is part of the APK, it is read only. You would have to regenerate the APK using the updated database.

Accessing the updated database itself could be an issue as the App's data is protected in devices that aren't rooted.

If you are using a device connected to Android Studio then you may be able to copy the updated database file(s) using device explorer into the asses folder. Noting that if the database uses Write-Ahead logging (WAL) that you may have the added complication of the -wal and -shm files, if there are any uncommitted changes. Ideally you would ensure that the database is closed, this should commit all changes, the -wal file should should then be 0 bytes or not exist in which case it is safe to just copy the database file itself.

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

Copying SQLite database from assets folder issue

The solution to my problem is this:

Since Android Studio uses the new Gradle-based build system, you should be putting assets/ inside of the source sets example myproject/src/main/assets/.

I created my own assets folder and put it where Eclipse usually puts it... which caused all these problems for me.

.How to copy files from project assets folder to device data folder in android studio?

So, are the files supposed to be automatically copied over to device? If not, how can I copy the files?

Yes it will BUT only when an attempt is made to access the database. Just instantiating the class that extends SQLiteAssetHelper will not copy the database and thus if that is all you do then the database will not be visible.

The steps when using SQliteAssetHelper to take should be :-

  1. Create your project.
  2. Amend the build.gradle to include implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:+' in the dependencies section.
  3. Create the assets folder and then the databases folder in the assets folder and
  4. Copy the database file into the databases folder.
  5. Create the Database Helper class that extends SQliteAssetHelper.
  6. Instantiate the Database Helper
  7. Access the database (this is when the database is copied).

If when doing step 5 you use, as an example (based upon the information in the question) :-

public class DatabaseHelper extends SQLiteAssetHelper {

public static final String DATABASENAME = "databasename.db"; //<<<<<<<<< MUST match file name in assets/databases
public static final int DATABASEVERSION = 1;

public DatabaseHelper(Context context) {
super(context, DATABASENAME, null, DATABASEVERSION);
this.getWritableDatabase(); //<<<<< will force database access and thus copy database from assets
}
}

Then when doing 6 (instantiating the database helper), then 7 is done because this.getWritableDatabase(); accesses (implicitly opens) the database.

e.g.

public class MainActivity extends AppCompatActivity {

DatabaseHelper mDBHelper; //<<<<< declares the database helper

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHelper = new DatabaseHelper(this); // instantiates the database helper
}
}

android - Cannot copy database from assets folder : API 24

The issue is likely that the databases directoryr does not exist (it will not for a newly installed App).

Thus you need to create the directory if it doesn't exist. e.g. :-

private fun installDatabaseFromAssets() {
val inputStream = context.assets.open("$ASSETS_PATH/$DATABASE_NAME.db")
val dbFile = File(context.getDatabasePath(DATABASE_NAME).toString())
if (!dbFile.exists()) {
if (!dbFile.parentFile.exists()) {
dbFile.parentFile.mkdirs()
}
}
try {
//val outputFile = File(context.getDatabasePath(DATABASE_NAME).path)
val outputStream = FileOutputStream(dbFile)

inputStream.copyTo(outputStream)
inputStream.close()
outputStream.flush()
outputStream.close()
} catch (exception: Throwable) {
throw RuntimeException("The $DATABASE_NAME database couldn't be installed.", exception)
}
}


Related Topics



Leave a reply



Submit