2012-06-08 10 views
5

utilizo este tutorial: Tutorial Custom databaseActualiza la base de datos SQLite que copio de carpeta de activos (Android)

copio la base de datos de la carpeta activos y copiarlo en el dispositivo (o emulador). Todo es correcto. Veo mi base de datos en perspectiva DDMS. Pero quiero actualizar mi base de datos aslo veces así lo hice:

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

y modificar ONUPGRADE método:

@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 correr todavía tengo versión antigua de la base de datos en el dispositivo. Cómo puedo eliminar una versión anterior de la base de datos y copiar una nueva. 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 funciona).

me pega mi todo el 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 me puede dar la razón o la razón por la única pista t trabajo este don'.

Respuesta

5

android ya abrió el db cuando se llama a la función onUpgrade(). No creo que sea posible eliminarlo en este momento. revisa el registro para más información. si quieres hacerlo de esta manera, debes mover el código de eliminación y copiado a un lugar donde el db aún no esté abierto.

+0

Sí, tiene usted razón. Lo que hice ? Utilicé preferencia compartida para firmar una nueva versión de la base de datos y eliminé la base de datos antes de usar este objeto. Gracias. – kolek

+2

@kolek: ¿Puedes compartir la solución con todos? También necesito algo similar. –

+0

¿Por qué no comparte la solución, Kolek? Por favor, muchos chicos lo necesitan. –

2

Pruebe este código ... Creo que va a resolver su 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); 
} 
0

Puede eliminar el Db antiguo antes de actualizar el 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(); 
} 
0

Sólo una adición:

en CreateDatabase() existe la siguiente comprobación;

this.getReadableDatabase();

Esto comprueba si ya hay una base de datos con el nombre proporcionado y si no crea una base de datos vacía, de modo 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. Dispositivos principalmente más antiguos. No sé exactamente por qué, pero parece que la función getReadableDatabase() no solo obtiene la base de datos sino que también la abre. Si luego copia 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á errores de tabla no existe.

Así que con el fin de hacer que funcione en todos los dispositivos que debe modificarlo para las siguientes líneas:

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

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

1

Cuando la base de datos se copia de los activos, de forma predeterminada la versión es 0. En su método para copiar databse de los activos, configure su versión utilizando el método setVersion(int version) para su objeto de base de datos. Si existe db, luego verifique su versión por el método getVersion() en su objeto de base de datos. Ahora maneja su OnUpgrade tú mismo, es decirsi db evrsion se ha actualizado noe, actualice la base de datos y luego setVersion(int new dbVersion).

0

La idea principal es que debe usar SharedPreferences para almacenar su versión de base de datos siempre que cree la nueva base de datos.
Después de eso, cuando se crea la base de datos, debe comprobar si la base de datos tiene una nueva versión a continuación, se elimina la base de datos antigua y crear una nueva obra
Este código 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) { 
     } 
    } 
Cuestiones relacionadas