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
How to Maintain Multi Layers of Imageviews and Keep Their Aspect Ratio Based on the Largest One
Manifest Merger Fails for Appcomponentfactory
Error: Fix the Version Conflict (Google-Services Plugin)
How to Define a Circle Shape in an Android Xml Drawable File
Transfer Data Between iOS and Android via Bluetooth
Non-Scrollable Listview Inside Scrollview
Installation App Blocked by Play Protect
Android Dex Gives a Bufferoverflowexception When Building
How to Set Layout_Gravity Programmatically
How to Change Progressbar's Progress Indicator Color in Android
Is This the Right Way to Clean-Up Fragment Back Stack When Leaving a Deeply Nested Stack
How to Set Up Android Emulator Proxy Settings
How to Copy Text Programmatically in My Android App
Get Current Location of User in Android Without Using Gps or Internet