0

Considering that my application is still in development, from time to time error appears that have influence on my database connected with the application. Because I have already test data, that I don't want to enter every time something goes wrong, I want to implement a simple import / export functionality.

I recently stumbled over this question, which is more or less what I want. I show you my code implemented. The export function works fine, I can test it with a SQLIte Database application from the android market. The problem is the import. It shows me the Toast, that everything gone good, but nothing happens. Still, I'm not quite sure if I'm doing it right.

In the MainMenuActivity I've implemented following methods:

(...)

public boolean onCreateOptionsMenu(Menu menu){
    menu.add(1, Menu.FIRST, Menu.FIRST, "backup DB").setIcon(R.drawable.ic_action_save);
    menu.add(1, Menu.FIRST+1, Menu.FIRST+1, "import DB").setIcon(R.drawable.ic_action_upload);
    return super.onCreateOptionsMenu(menu);
}

(...)

public boolean onOptionsItemSelected(MenuItem item){
    switch(item.getItemId()){
    case 1:
        backupDatabase();
        return true;
    case 2:
        importDatabase();
        return true;
        default:
        break;
    }
    return super.onOptionsItemSelected(item);
}


private void backupDatabase(){
    try{
         File sd = Environment.getExternalStorageDirectory();
         File data = Environment.getDataDirectory();

         if (sd.canWrite()) {
             String currentDBPath = "//data//challenge.main//databases//DBCHALLENGES";
             String backupDBPath = "DBCHALLENGES";
             File currentDB = new File(data, currentDBPath);
             File backupDB = new File(sd, backupDBPath);

             FileChannel src = new FileInputStream(currentDB).getChannel();
             FileChannel dst = new FileOutputStream(backupDB).getChannel();
             dst.transferFrom(src, 0, src.size());
             src.close();
             dst.close();
             Toast.makeText(getBaseContext(), "Successfully backed up database!", Toast.LENGTH_LONG).show();
         }
    }catch (IOException e){
        Toast.makeText(getBaseContext(), "Error in backing up database!", Toast.LENGTH_LONG).show();
    }
}


private void importDatabase(){
    datasource = new CustomDataSource(this);
    datasource.open();
    try{
        datasource.importDatabase("DBCHALLENGES");
        Toast.makeText(getBaseContext(), "Successfully imported database!", Toast.LENGTH_LONG).show();
    }catch (IOException e){
        Toast.makeText(getBaseContext(), "Error in importing database!", Toast.LENGTH_LONG).show();
    }finally{
        datasource.close();
    }
}

in my CustomDataSource:

public boolean importDatabase(String dbPath) throws IOException{
    return dbHelper.importDatabase(dbPath);
}

and finally in the DBHelper extending SQLiteOpenHelper

public boolean importDatabase(String dbPath) throws IOException{
    close();
    File newDB = new File(dbPath);
    File oldDB = new File("//data//challenge.main//databases//DBCHALLENGES");
    if(newDB.exists()){
        FileUtils.copyFile(new FileInputStream(newDB), new FileOutputStream(oldDB));
        getWritableDatabase().close();
        return true;
    }

    return false;
}

However, pressing on the import Button, the positive Toast appears, saying that the import was successfull. But my application, empty before, is still empty. The backed up database is supposed to be located on the first level of the internal storage, what it does. I think, maybe I'm confusing something with the paths, but I can't get through what exactly.

Community
  • 1
  • 1
Valentino Ru
  • 4,964
  • 12
  • 43
  • 78
  • trivial but just asking, have you set the storage permission in the manifest file? – Lazy Ninja Nov 07 '12 at 01:05
  • of course, if think otherwise I couldn't even export the db – Valentino Ru Nov 07 '12 at 01:11
  • @ValentinoRu : Why are you using `//` as your path separator? It should just be `/` e.g., `new File("/data/challenge.main/databases/DBCHALLENGES");` – Squonk Nov 07 '12 at 01:31
  • is there any difference in using one or two '/'? I saw this in an example which I cannot find right now, and how said, the exporting works with this path – Valentino Ru Nov 07 '12 at 01:56

1 Answers1

2

Try this:

private void importDatabase(String inputFileName) throws IOException
{
    InputStream mInput = new FileInputStream(inputFileName);
    String outFileName = YOUR_DB_PATH_HERE;
    OutputStream mOutput = new FileOutputStream(outFileName);
    byte[] mBuffer = new byte[1024];
    int mLength;
    while ((mLength = mInput.read(mBuffer))>0)
    {
        mOutput.write(mBuffer, 0, mLength);
    }
    mOutput.flush();
    mOutput.close();
    mInput.close();
}
Yaqub Ahmad
  • 27,569
  • 23
  • 102
  • 149
  • 1
    `InputStream mInput = new FileOutputStream(inputFileName);` - I think that should be `new FileInputStream(inputFileName)` – Squonk Nov 07 '12 at 01:26
  • No problem. I figured it was a typo. – Squonk Nov 07 '12 at 01:44
  • i suppose that for the inputfileName I can simply take 'DBCHALLENGES' (since it's on the firts level of the external storage)? and for outfileName the path to the 'real' database? (cannot test it at the moment, sorry). – Valentino Ru Nov 07 '12 at 01:55