Android: copia la base de datos de la carpeta de activos, pero sólo obtiene un archivo vacío

Chicos, tengo el problema al copiar la base de datos de la carpeta de activos locales a / data / data / package_name / directorio de bases de datos. Como uso el http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ tutorial para hacerlo, sólo puedo obtener un archivo vacío.

He citado la parte del método copyDataBase () y no hay diferencia. Cada vez que se inicie la aplicación, creará el directorio y la base de datos vacía. Entonces, ¿hay alguna manera de hacer que copyDataBase () funcione?

¡¡Muchas gracias!!

No copiaría ningún formulario de base de datos de la carpeta de assets . Si necesita alguna entrada estándar en su base de datos, puede agregarla utilizando INSERT s en su método onCreate() .


Actualización: Puesto que esto es conseguir abajo votado por estar equivocado (que es un poco correcto) y no puedo eliminarlo, aquí hay una pequeña actualización.

Yo diría que depende de cuántas entradas estándar que desea agregar a su base de datos. Si es sólo uno o dos, el envío de un paquete de DB podría no valer la pena.

De todas formas, algunas aplicaciones vienen con bases de datos bastante grandes (por ejemplo, una colección de recetas). Obviamente, no puede agregar todos estos en el código.

  • Para pequeñas entradas de prueba, todavía preferiría simplemente agregarlas en onCreate() .
  • Para bases de datos más grandes, debe pre-poblarlas y enviar em junto con su aplicación.

Para que funcione más tarde, tendrá que copiar el archivo de base de datos de assets/ a su carpeta de aplicaciones. Hay una bonita biblioteca para manejar eso para ti: android-sqlite-asset-helper

¿Por qué no copia de los activos? Es perfectamente normal hacerlo. Pero no se puede hacer en el onCreate, en ese momento ya se ha creado una base de datos vacía. Tienes que hacerlo antes. Normalmente lo hago en una anulación de getWriteableDatabase, algo así como

 public synchronized SQLiteDatabase getWritableDatabase() { SQLiteDatabase db = null; if (!doesDatabaseExist()) { try { copyDatabase(); db = super.getWritableDatabase(); } catch(Exception ex) { Log.e("Database Log", getDatabasePath() + " failed to copy correctly. " + ex.getLocalizedMessage()); } } else { db = super.getWritableDatabase(); } return db; } 

A la derecha encima del ejemplo trabajó para mí de esta manera:

 db = super.getWritableDatabase(); db.close; copyDatabase(); 

De lo contrario tengo un error de E / S;

Aquí está el código simple y conveniente que utilizo:

 public class DataBaseImportHelper { private DataBaseImportHelper() {}; // Avoid instantiation /** * Creates a empty database on the system and rewrites it with your own database. */ public static boolean importDataBase(Context context) { InputStream myInput = null; OutputStream myOutput = null; try { // Open local db from assets as the input stream myInput = context.getAssets().open(DATABASE_NAME); createEmptyDatabase(context); // See this method below // Open the empty db as the output stream myOutput = new FileOutputStream(getDatabaseFile(context)); // 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(); myInput.close(); myOutput.close(); return true; } catch (IOException e) { e.printStackTrace(); } return false; } /** * Check if the database already exists. * @return true if it exists, false if it doesn't */ public static boolean isDatabaseExists(Context context) { return getDatabaseFile(context).exists(); } private static File getDatabaseFile(Context context) { return context.getDatabasePath(DatabaseHelper.DATABASE_NAME); } /** * Create an empty database into the default application database * folder.So we are gonna be able to overwrite that database with our database */ private static void createEmptyDatabase(Context context) { // use anonimous helper to create empty database new SQLiteOpenHelper(context, DatabaseHelper.DATABASE_NAME, null, 1) { // Methods are empty. We don`t need to override them @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } @Override public void onCreate(SQLiteDatabase db) { } }.getReadableDatabase().close(); } 

}

Y usando en código:

 if(!DataBaseImportHelper.isDatabaseExists(this)){ if (!DataBaseImportHelper.importDataBase(this)){ throw new IllegalStateException("Database doesn`t exist and hasn`t been copied!"); } } 

No sé si todavía es útil, pero aquí es la solución para otros que llegan aquí para ver el awnser. El código que usó, funciona para la mayoría de los teléfonos, algunos teléfonos antiguos tienen un comportamiento diferente con la función getReadableDatabase (). Por lo tanto, su problema no está en la función copyDataBase sino en la función createDataBase.

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.

  • Obtener el resultado del cursor y convertirlo en una cadena para TextView
  • Android SQLite Facilidad de reversión de transacciones?
  • Cursor de cierre en la base de datos SQLite explícitamente, necesarios o no necesarios?
  • Cómo almacenar (imagen de mapa de bits) y recuperar la imagen de la base de datos sqlite en android?
  • Sync SQLite / tabla de base de datos de Android a la tabla de base de datos MySQL remoto (a través de PHP)
  • Sqlite en Android: Cómo crear una función sqlite dist db - que se utilizará en la aplicación para calcular la distancia utilizando lat, largo
  • Cómo persistir el permiso en android API 19 (KitKat)?
  • Cómo almacenar la clave utilizada en SQLCipher para android
  • Cómo deshabilitar el botón Borrar datos en Información de aplicación de la aplicación Administrar
  • Sqlite - en rebaja
  • Calcular la distancia entre dos puntos directamente en SQLite
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.