Actualizar la base de datos sqlite que copio de la carpeta de activos (Android)

Utilizo este tutorial: Tutorial Base de datos personalizada

Copiar la base de datos de la carpeta de activos y copiarla a mi dispositivo (o emulador). Todo es correcto. Veo mi base de datos en perspectiva de DDMS. Pero también quiero actualizar mi base de datos a veces, así que lo hice:

super(context, DB_NAME, null, 2); //changed version from 1 to 2 

Y modificar el método onUpgrade:

 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if(newVersion > oldVersion){ this.myContext.deleteDatabase(DB_NAME); try { this.copyDataBase(); } catch (IOException e) { e.printStackTrace(); } } } 

Pero después de ejecutar todavía tengo la versión antigua de la base de datos en mi dispositivo. Cómo puedo eliminar la versión antigua de la base de datos y copiar nuevo. DB_NAME es el nombre de mi base de datos (con formato, pero no ruta) y copyDataBase () es un método que copia la base de datos al dispositivo (y su trabajo).

Me pego todo mi código:

 public class DataBaseHelper extends SQLiteOpenHelper{ private static String DB_PATH = "/data/data/sitcom.quiz/databases/"; private static String DB_NAME = "sitcoms.sqlite"; private SQLiteDatabase myDataBase; private final Context myContext; public DataBaseHelper(Context context) { super(context, DB_NAME, null, 4); this.myContext = context; } public void createDataBase() throws IOException{ boolean dbExist = checkDataBase(); if(dbExist){ //do nothing - database already exist }else{ this.getReadableDatabase(); try { copyDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } } } 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 ? true : false; } 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(); } public void openDataBase() throws SQLException{ //Open the database String myPath = DB_PATH + DB_NAME; myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } @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.d("adas", "dasd"); if(newVersion > oldVersion){ String myPath = DB_PATH + DB_NAME; this.myContext.deleteDatabase(myPath); try { this.copyDataBase(); } catch (IOException e) { e.printStackTrace(); } } } } 

Y mi actividad:

 DataBaseHelper myDbHelper = new DataBaseHelper(this); myDbHelper = new DataBaseHelper(this); try { myDbHelper.createDataBase(); } catch (IOException ioe) { throw new Error("Unable to create database"); } try { myDbHelper.openDataBase(); }catch(SQLException sqle){ throw sqle; } 

Gracias si usted puede darme la razón o la indirecta solamente porqué ésta no trabaja.

Android ya abrió el db cuando se llama a la función onUpgrade (). No creo que sea posible eliminarlo en este momento. Verifique el registro para más información. Si quieres hacerlo de esta manera, necesitas mover el código de borrar y copiar a un lugar donde el db no está abierto todavía.

Prueba este código … Creo que resolverá tu problema.

 public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { Log.w(DatabaseHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); database.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME); onCreate(database); } 

Cuando se copia la base de datos de los activos, por defecto la versión es 0. En su método para copiar databse de los activos, establezca su versión utilizando el método setVersion(int version) para su objeto de base de datos. Si db existe, compruebe su versión por el método getVersion() en su objeto de base de datos. Ahora manejar su onUpgrade usted mismo, es decir, si db evrsion se ha actualizado noe, a continuación, actualizar la base de datos y luego setVersion(int new dbVersion) .

Puede eliminar el Db anterior antes de actualizar DB.

  if(dbExist){ Log.v("com.db","db exists"); myContext.deleteDatabase(DB_NAME);`enter code here` //openDataBase(); //do nothing - database already exist }else{ Log.v("com.db","dbnot exists"); //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(); } 

Sólo una adición:

En createDataBase () hay la siguiente comprobación;

This.getReadableDatabase ();

Esto comprueba si ya existe una base de datos con el nombre proporcionado y si no crea una base de datos vacía tal que se puede sobrescribir con la de la carpeta de activos. En los dispositivos más nuevos esto funciona sin problemas, pero hay algunos dispositivos en los que esto no funciona. Principalmente los dispositivos más antiguos. No sé exactamente por qué, pero parece que la función getReadableDatabase () no sólo recibe la base de datos sino que también la abre. Si a continuación, copiar la base de datos de la carpeta de activos sobre ella, todavía tiene el puntero a una base de datos vacía y obtendrá tabla no existen errores.

Así que para que funcione en todos los dispositivos, debes modificarlo a las siguientes líneas:

 SQLiteDatabase db = this.getReadableDatabase(); if (db.isOpen()){ db.close(); } 

Incluso si la base de datos se abre en el cheque, se cierra a partir de entonces y no le dará más problemas.

La idea principal es que debe usar SharedPreferences para almacenar la versión de la base de datos siempre que cree la nueva base de datos.
Después de eso, cuando usted crea la base de datos, usted debe comprobar si la base de datos tiene nueva versión entonces usted suprime la vieja base de datos y crea una nueva
Este código funciona conmigo

 private static class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "database.name"; private static final int DATABASE_VERSION = 1; private static final String KEY_DB_VER = "database_version"; private final Context mContext; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); mContext = context; initialize(); } /** * Initializes database. Creates database if doesn't exist. */ private void initialize() { if (databaseExists()) { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(mContext); int dbVersion = prefs.getInt(KEY_DB_VER, 1); // if (DATABASE_VERSION != dbVersion) { File dbFile = mContext.getDatabasePath(DATABASE_NAME); // delete the old databse if (!dbFile.delete()) { Log.w(TAG, "Unable to update database"); } } } // create database if needed if (!databaseExists()) { createDatabase(); } } /** * Returns true if database file exists, false otherwise. * @return */ private boolean databaseExists() { File dbFile = mContext.getDatabasePath(DATABASE_NAME); return dbFile.exists(); } public void createDataBase() throws IOException { // If database not exists copy it from the assets boolean mDataBaseExist = databaseExists(); if (!mDataBaseExist) { this.getReadableDatabase(); this.close(); try { // Copy the database from assests copyDataBase(); //**save the database version by SharedPreferences** SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(mContext); SharedPreferences.Editor editor = prefs.edit(); editor.putInt(KEY_DB_VER, DATABASE_VERSION); editor.commit(); Log.e(TAG, "createDatabase database created"); } catch (IOException mIOException) { throw new Error("ErrorCopyingDataBase"); } } } // Copy the database from assets private void copyDataBase() throws IOException { Log.i("TAG", "copy database"); InputStream mInput = mContext.getAssets().open(DB_NAME); String outFileName = DB_PATH + DB_NAME; 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(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } 
  • Sqlite base de datos en el idioma persa
  • Simple coursor adaptador con base de datos SQLite y custmize listview
  • Mantenimiento de un ListView donde cada elemento de lista tiene una relación de uno a muchos
  • Android SQLite Rendimiento con índices
  • ¿Un cursor SQLite vacío devolverá true para isBeforeFirst, isAfterLast, ambos o ninguno?
  • Tamaño máximo de la base de datos SQLite en la memoria de una aplicación para Android?
  • Borrar datos antiguos de caché con robospice ormlite
  • Cómo comprobar si BLOB es nulo
  • Transacción de la base de datos Android
  • La base de datos SQLite de Android está bloqueada
  • DB SQLite de Android Cuando cerrar
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.