SQLiteOpenHelper onCreate no crea base de datos – o se está sobrescribiendo inmediatamente

Tengo mi base de datos almacenada en mi carpeta de los activos y copiada sobre en la época de la ejecución. Tengo actualmente una actividad simple que hace una llamada simple de la base de datos:

DBAdapter adapter = new DBAdapter(HomeActivity.this); final SQLiteDatabase db = adapter.getReadableDatabase(); final Cursor c = db.query("exercises", new String[] { "name" }, null, null, null, null, null); startManagingCursor(c); if (c.moveToFirst()) Log.e(TAG, c.getString(0)); else Log.e(TAG,"No dice"); 

Y abajo está mi DBAdapter.java (que extiende el ayudante abierto):

 public class DBAdapter extends SQLiteOpenHelper { private static final int DB_VERSION = 1; private static String DB_PATH = ""; private static final String DB_NAME = "gymrat.db"; private final Context myContext; private static final String TAG = "GymRat.DBAdapter"; /** * Constructor Takes and keeps a reference of the passed context in order to * access to the application assets and resources. * * @param context */ public DBAdapter(Context context) { super(context, DB_NAME, null, DB_VERSION); this.myContext = context; DB_PATH = "/data/data/" + context.getApplicationContext().getPackageName() + "/databases/"; } /** * 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 transferring bytestream. * */ private void copyDatabase() throws IOException { InputStream myInput = myContext.getAssets().open(DB_NAME); String outFileName = DB_PATH + DB_NAME; OutputStream myOutput = new FileOutputStream(outFileName); byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } myOutput.flush(); myOutput.close(); myInput.close(); } /** * Call on creating data base for example for creating tables at run time */ @Override public void onCreate(SQLiteDatabase db) { Log.e(TAG, "onCreate"); try { copyDatabase(); } catch (IOException e) { Log.e(TAG,"IOException copying Database"); } } @Override public void onOpen(SQLiteDatabase db) { Log.e(TAG, "onOpen"); try { db.rawQuery("select * from exercises", null); } catch ( SQLiteException e) { Log.e(TAG,"DB copy didn't work"); try { copyDatabase(); } catch (IOException e1) { Log.e(TAG,"IOException recopying DB"); } } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.e(TAG, "Upgrading"); } } 

Tomé este adaptador de aquí y lo modifiqué puesto que no parecía utilizar la funcionalidad de OpenHelper.

Mi Problema: Cuando mi aplicación se ejecuta por primera vez después de instalar, o después de limpiar los datos de la aplicación, onCreate se llama primero como yo esperaría, y llama al método copyDatabase. El problema es que la base de datos no se copia – o si lo hace se sobrescribe inmediatamente. En su lugar, se crea una base de datos predeterminada con sólo una tabla "meta_datos android", haciendo que la consulta de mi actividad lance una excepción porque la tabla no existe.

Si vuelvo a copiar la base de datos en el método onOpen funciona bien. ¿Estoy haciendo algo fuera de servicio o falta alguna llamada que está causando que SQLiteOpenHelper cree una base de datos predeterminada? La base de datos predeterminada creada utiliza el mismo nombre y el mismo número de versión especificado en el constructor.

Ahora mismo, como se puede ver, estoy recurriendo a usar una consulta ficticia en onOpen para ver si existe la tabla esperada y si no va adelante y volver a copiar la base de datos. Otra opción es simplemente establecer una bandera cuando onCreate se llama señalización onOpen para copiar la base de datos. Obviamente estos son un poco hacky y estoy muy curioso de lo que está pasando.

Planeo mover las llamadas reales de la base de datos a las clases auxiliares separadas fuera de la actividad, yo estaba llamando simplemente el db directamente para probarlo.

Si desea copiar la base de datos de los activos a la primera ejecución y abrir la base de datos desde data / data / programa.nombre / base de datos, debe usar el código algo como esto:

 public class YourDatabase extends SQLiteOpenHelper public YourDatabase(Context context) { super(context, DatabaseName, null, DATABASE_VERSION); this.dbContext = context; // checking database and open it if exists if (checkDataBase()) { openDataBase(); } else { try { this.getReadableDatabase(); copyDataBase(); this.close(); openDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } Toast.makeText(context, "Initial database is created", Toast.LENGTH_LONG).show(); } } 

Respuesta completa que puedes leer de esta pregunta

  • Agregar una columna a la tabla de SQLite en Android?
  • Consulta SQLite desde varias tablas utilizando SQLiteDatabase
  • ¿Se ha construido SQLite en Android con el tokenizador ICU habilitado para FTS?
  • ¿Cómo insertar un registro SQLite con una fecha y hora establecida en 'ahora' en la aplicación de Android?
  • ¿Cómo actualizar el esquema de la tabla después de una actualización de la aplicación en Android?
  • Cómo probar la actualización de la base de datos sqlite antes de cargar la nueva versión de mi aplicación en la tienda de juegos en android
  • ¿Por qué algunos métodos SQLite esperan argumentos como un objeto , mientras que otros necesitan una cadena ?
  • Cómo personalizar FTS tokenizer en Android
  • ¿Cómo utilizar mi propia base de datos sqlite?
  • Android Sqlite IN, sin sintaxis
  • SQLite incapaz de abrir el archivo de base de datos (código 14) en la consulta "SELECT" frecuente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.