Problema de corrupción de bases de datos precargado en la aplicación de Android

Tengo una aplicación de Android que comienza por la descarga de una gran base de datos a la sdcard (un poco más de 50 MB) en un asynctask. El código de descarga es el siguiente.

HttpURLConnection conexion = (HttpURLConnection) url.openConnection(); if(filePath.exists() && filePath.length() > 10000.00) { downloaded = (int) filePath.length(); conexion.setRequestProperty("Range", "bytes=" + (filePath.length()) + "-"); } else conexion.setRequestProperty("Range", "bytes=" + downloaded + "-"); conexion.setDoInput(true); conexion.setDoOutput(true); conexion.setUseCaches(false); conexion.connect(); 

 try { totalFileLength = lengthOfFile + downloaded; progressDialog.setMax(lengthOfFile + downloaded); // downlod the file input = new BufferedInputStream(conexion.getInputStream()); output = (downloaded==0)? new FileOutputStream(filePath): new FileOutputStream(filePath,true); bout = new BufferedOutputStream(output, 1024); byte data[] = new byte[1024]; while ((count = input.read(data, 0, 1024)) >= 0 && running) { downloaded += count; // publishing the progress.... //onProgressUpdate((int)(downloaded*100/lengthOfFile)); progressDialog.setProgress(downloaded); bout.write(data, 0, count); } } catch (Exception e) { ... } finally { try { input.close(); bout.flush(); bout.close(); } catch(IOException e) { ... } } 

Después de descargar el archivo completamente, abrir la base de datos y añadir una tabla a ella.

 try { myDbHelper.myDataBase.execSQL("CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)"); success = true; } catch (SQLException sqle) { throw sqle; } 

Ahora, este código funciona maravillosamente en cada dispositivo en el que lo ejecuto, pero varios de mis usuarios están recibiendo este error en la línea execSQL. Parece que no está funcionando en el Samsung Galaxy SII solo (no ha habido una queja y stacktrace posterior con este error con cualquier otro teléfono), pero no estoy completamente seguro de su sólo este teléfono.

 java.lang.RuntimeException: Unable to start activity ComponentInfo{net.daleroy.fungifieldguide/net.daleroy.fungifieldguide.activities.FungiFieldGuide}: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) at android.app.ActivityThread.access$1500(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3691) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) at dalvik.system.NativeStart.main(Native Method) Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER) at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method) at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1904) at net.daleroy.fungifieldguide.services.MushroomService.MakeFavoriteTable(MushroomService.java:118) at net.daleroy.fungifieldguide.services.MushroomService.OpenDB(MushroomService.java:64) at net.daleroy.fungifieldguide.activities.FungiFieldGuide.onCreate(FungiFieldGuide.java:73) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615) 

He recibido una copia de la base de datos descargada de un usuario con sgs2 y la suma de comprobación del archivo está desactivada. También no puedo ver ningún dato o estructura de datos en el archivo cuando abro con sqlite manager (firefox plugin). Le dejo descargar una copia de la base de datos directamente y colocarla en su carpeta de datos y la aplicación funciona bien. Así que el problema está en algún lugar del proceso de descarga.

A partir del nivel API 9 (Android 2.3) puede utilizar DownloadManager para manejar descargas HTTP de larga ejecución:

El gestor de descargas es un servicio del sistema que gestiona descargas HTTP de larga ejecución. Los clientes pueden solicitar que se descargue un URI a un archivo de destino en particular. El gestor de descarga llevará a cabo la descarga en segundo plano, teniendo cuidado de las interacciones HTTP y reintentando las descargas después de los fallos oa través de los cambios de conectividad y los reinicios del sistema.

Aquí está el ejemplo del proyecto que demuestra el uso de DownloadManager: Android DownloadManager Ejemplo .

Creo que incluso se puede tratar de backport DownloadManager a las versiones anteriores de Android (si es necesario para apoyarlos). Su código fuente se puede encontrar aquí: DownloadManager.java

¿Está llamando a nivel y cierre en su outputtream? Me gusta esto:

 while ((count = input.read(data, 0, 1024)) >= 0 && running) { downloaded += count; progressDialog.setProgress(downloaded); bout.write(data, 0, count); } bout.flush(); bout.close(); 

Si no, empezaría con eso. He descargado un video con un código similar y encontré que para algunos dispositivos y algunos videos no llamar flush estaba dañando y lo que no jugable

Aquí hay otra pregunta que habla de este tipo de corrupción de base de datos Android – la imagen del disco de la base de datos es malformada .

Si no puede arreglar la base de datos cuando está en este estado, tal vez puede intentar descargarla de nuevo si y cuando se produce este error (suponiendo que este problema es raro y descargar la base de datos de nuevo puede solucionar el problema).

  • Contactos de Android: Colocación / clasificación local incorrecta
  • Android - La mejor manera de sincronizar SQLite con MySQL
  • Pasar una matriz de datos a una base de datos SQLite en android
  • IllegalStateException: Tablas no válidas al intentar consultar la base de datos con ContentProvider
  • Carga pesada en el hilo que causa problemas de memoria
  • Cómo convertir MDB a SQLite en Android
  • Android Studio vs idioma ruso
  • Ejemplos de proyectos sobre la copia de seguridad del archivo y las fotos de Sqlite en Google Drive mediante programación en Android
  • Cómo concat columnas en Android sqlite
  • RawQuery Vs. Database.query
  • Eficiente ejecución de consultas SQL por lotes en Android, para actualizar la base de datos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.