0

I'm coping a database from assets folder to my Device Sd Card using this code

private void copyDataBase() throws IOException {
        try {

            InputStream mInputStream = mContext.getAssets().open(DB_NAME);

            String outFileName = DB_PATH + DB_NAME;



            OutputStream mOutputStream = new FileOutputStream(outFileName);

            byte[] buffer = new byte[1024];
            int length;

            while ((length = mInputStream.read(buffer)) > 0) {
                mOutputStream.write(buffer, 0, length);
            }

            mOutputStream.flush();
            mOutputStream.close();
            mInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

it works fine and copies the database to my devices desired folder , but when I check the data in the tables , all the data are gone , tables are empty , I've searched in Stack to get a satisfactory idea , or answer , but they were all about how to copy , any idea?

rabar kareem
  • 620
  • 7
  • 28
  • its the path in sd card `static String DB_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Android/data/PYP/";` – rabar kareem Mar 10 '14 at 14:32
  • for details: the db in assets has data? only the db in sd card lost the information? – Manuel Spigolon Mar 19 '14 at 10:40
  • since you are trying to copy the data with the `database`, why you do not add the the data runtime? just an idea. – Saif Hamed Mar 19 '14 at 10:44
  • @Eomm my database is sqlite database , not .db – rabar kareem Mar 19 '14 at 20:07
  • 1
    db is a synonym of database and a sqlite database can have .db extension. But this is not the point: have you opened your database file with a browser like [sqlitebrowser](http://sqlitebrowser.sourceforge.net/)? The file is corrupted or you see correctly the information? – Manuel Spigolon Mar 20 '14 at 08:13
  • Can you check if your SQLiteOpenHelper's onUpgrade method does not have any logic to delete and recreate tables based on the database version? – Madala Mar 21 '14 at 03:35
  • @Eomm thanks for details , Yes I've opened the database , and it opens the database with all the tables but all of them are empty – rabar kareem Mar 22 '14 at 12:32
  • @Madala my Upgrade method is empty , I've write nothing there just override it – rabar kareem Mar 22 '14 at 12:33
  • Can you post the code that opens the database after it's copied from the asset folder? – Emanuel Moecklin Mar 25 '14 at 01:59

4 Answers4

1

I'm doing this right now and it's working..so I share my code..maybe this would help you.

File file = new File(Environment.getExternalStorageDirectory(), "my.db");

InputStream  in  = null;
OutputStream out = null;
try {
    in  = getAssets().open("my.db"); //.I'm in a service, so I don't need context
    out = new FileOutputStream(file);

    int count = 0; 
    byte[] buffer = new byte[1024*4];
    while ((count = in.read(buffer)) != -1) {
       out.write(buffer, 0, count);
       out.flush();
    }
 } catch (IOException err) {
    Log.e(TAG, err.getMessage(), err);

 } finally {
   if (in != null) 
      try { in.close(); } 
      catch (IOException ignore) {  }
   if (out != null) 
      try { out.close(); } 
      catch (IOException ignore) {  }
 }

Edit 1

Here the SQLiteOpenHelper code

public class SchemaHelper extends SQLiteOpenHelper {

    static final private String DATABASE_NAME = "my.db";
    static final private int DATABASE_VERSION = 1;  

    private SchemaHelper( Context context ) {
       super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate( SQLiteDatabase db ) {
       /* The database has 6 tables pre-populated */
       /* This one is the only created at runtime */
       /* and editable by the user */
       ShoppingListTable.onCreate(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
       /* The database has 6 tables pre-populated */
       /* This one is the only created at runtime */
       /* and editable by the user */
       ShoppingListTable.onUpgrade(db, oldVersion, newVersion);
    }
}

Edit 2

ShoppingListTable is an helper static class which define the column fields and the creation/upgrade. This is the only Table created at runtime, all the others are pre-created and pre-filled.

public class ShoppingListTable {

   static final public String COLUMN_PRODUCT_ID = BaseColumns._ID;
   static final public String COLUMN_PARSE_OBJECT_ID = "objectId";
   static final public String COLUMN_LAST_UPDATE = "lastUpdate";
   static final public String TABLE_NAME = "ShoppingList";

   static 
   public void onCreate(SQLiteDatabase database) {
      StringBuilder sql = new StringBuilder();
      sql.append("CREATE TABLE ").append(TABLE_NAME).append(" (");
      sql.append(COLUMN_PRODUCT_ID).append(" INTEGER PRIMARY KEY NOT NULL, ");
      sql.append(COLUMN_PARSE_OBJECT_ID).append(" TEXT, ");
      sql.append(COLUMN_LAST_UPDATE).append(" INTEGER DEFAULT -1, ");
      sql.append(COLUMN_SYNCSTATE).append(" INTEGER DEFAULT 0 ");
      sql.append(");");

      database.execSQL(sql.toString());
   }

   static
   public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
      Log.w( ShoppingListTable.class.getName(), "Upgrading database from version "
         + oldVersion + " to " + newVersion + ", which will destroy all old data" );
      database.execSQL("DROP TABLE IF EXISTS " + ShoppingListTable.TABLE_NAME );
      ShoppingListTable.onCreate(database);
   }
}
Luca Sepe
  • 2,345
  • 1
  • 17
  • 22
  • That's the same as my copy function , it is not working for this issue – rabar kareem Mar 22 '14 at 16:07
  • I see..but, believe me I launched again my app right now and it worked as usual. I have a preloaded db in assets folder and starting an IntentService I execute exactly the code above. The db copied to the sd card have all the data. If would be helpful I can post my IntentService code..but it's nothing special, just a wrapper to the code above. – Luca Sepe Mar 22 '14 at 16:38
  • Ok , what's in your Upgrade method exactly ? please post it to me – rabar kareem Mar 22 '14 at 17:22
  • Since (in my case) the database is pre-populated and the user can "operate" on just one table, only this table is created and eventually upgraded in the SQLiteOpenHelper code. – Luca Sepe Mar 22 '14 at 17:35
  • @rabarkareem I posted the code of my SQLiteOpenHelper ..please don't give me another -1 :-P :-P .. if you want i can post also the IntentService...but as I told it's nothing special – Luca Sepe Mar 22 '14 at 17:44
  • Thanks a lot , No the -1 wasn't by me , but let me give you +1 instead P – rabar kareem Mar 22 '14 at 18:53
  • thank you very much :-) but, above all, did you solved? – Luca Sepe Mar 22 '14 at 18:55
  • I'm trying till now , but what is `ShoppingListTable` is it the `SqliteDatabase`? – rabar kareem Mar 24 '14 at 16:50
  • ShoppingListTable is a simple static class that defines the Table cols and the SQL queries for creation. I'll post it. – Luca Sepe Mar 24 '14 at 17:34
  • @LuS I am also facing same [problem](http://stackoverflow.com/questions/24838329/copy-db-from-assets-to-db-folder-in-device-memory) but this code isn't working for me. Please help. – Amit Anand Jul 30 '14 at 10:25
1

try this. This work for me...

String outFileName = "/data/data/" + ctx.getPackageName() + "/databases/YOUR_DB";

Preinitialized DB should not have any file extension. Hope this helps you

Dima
  • 158
  • 6
0

Try to use Buffered Stream as mentioned below with proper while condition and try..catch.

BufferedInputStream in = new BufferedInputStream(new FileInputStream(fromFileName));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(toFileName));
byte[] buff = new byte[1024];
int len;
try{
while ((len = in.read(buff,0,buff.lenght())) > 0){
  out.write(buff, 0, len);
}
}catch(Exception e){
  e.printStackTrace()
}
out.flush();    
out.close();
in.close();
MKJParekh
  • 32,883
  • 11
  • 84
  • 97
-1

DB file shoud be

static File DB_FILE = context.getDatabasePath("databasename");

If your database is larger than 1MiB you have to split it into chunks

Check my answer here

Getting “Failed to open database” error when copying a sqlite database from assets In Android 4.2

Also you can take a look here

Load files bigger than 1M from assets folder

Community
  • 1
  • 1
Yaroslav Mytkalyk
  • 16,503
  • 10
  • 70
  • 96
  • your answers are all about a database more than 1 MB , but my database is containing a few tables with few data in them – rabar kareem Mar 19 '14 at 20:29