0

I have application which is already published I haven't added DATABASE_VERSION in it.

Now I want to update database with some new rows in 3 of my tables (~100 rows)

Im deleting database on Upgrade and copying new database file.

I have database file in assets. but on upgrading application it stops working. Actually dubug app works fine but release apk stops working.

here is my code

private static String DB_PATH = "/data/data/my.package.name/databases/";

private static String DB_NAME = "file.sqlite";
private static final int DATABASE_VERSION = 2;

private SQLiteDatabase myDataBase;

private final Context myContext;
 *
 * @param context
 */
public DataBaseHelper(Context context) {

    super(context, DB_NAME, null, DATABASE_VERSION);
    this.myContext = context;
}

/**
 * Creates a empty database on the system and rewrites it with your own database.
 */
public void createDataBase() {

    boolean dbExist = checkDataBase();

    if (dbExist) {
//do nothing - database already exist
    } else {

 //By calling this method and empty database will be created into the default system path
 //of your application so we are gonna be able to overwrite that database with our database.
        this.getReadableDatabase();

        try {

            copyDataBase();

        } catch (IOException e) {

            throw new Error("Error copying database");

        }
    }

}

/**
 * Check if the database already exist to avoid re-copying the file each time you open the application.
 *
 * @return true if it exists, false if it doesn't
 */
private boolean checkDataBase() {

    SQLiteDatabase checkDB = null;

    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    } catch (SQLiteException e) {

 //database does't exist yet.

    }

    if (checkDB != null) {
        checkDB.close();
    }
    return checkDB != null;
}

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

}

@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) {
    myContext.deleteDatabase(DB_NAME);
    Toast.makeText(myContext,"done",Toast.LENGTH_SHORT).show();
    createDataBase();
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
akshay bhange
  • 2,320
  • 2
  • 28
  • 46

2 Answers2

0

I believe that here is your problem:

public void createDataBase() {
    ...
    this.getReadableDatabase();
    try {
        copyDataBase();
    } catch (IOException e) {
        throw new Error("Error copying database");
    }
}

this.getReadableDatabase() opens your database for read. Then, copyDataBase() try to write your asset file. However, since the file is opened for read, you can't write and you get an error.

So, I think you must update createDataBase() as follows:

public void createDataBase() {
    boolean dbExist = checkDataBase();
    if (dbExist) {
        //do nothing - database already exist
    } else {
        SQLiteDatabase checkDB = getReadableDatabase();
        checkDB.close();
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}
guipivoto
  • 18,327
  • 9
  • 60
  • 75
0

If you do not care about the data in the old database, you don't need to do any form of upgrading or versioning. Just change the file name. So the new APK creates a new file, and you can delete the old one whenever you like.

Please note that SQLiteAssetHelper can help you with the copying stuff.

CL.
  • 173,858
  • 17
  • 217
  • 259