I have an Android app that starts by loading a large database onto an SD card (a little over 50 MB) in the asintet. The download code is as follows.
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) { ... } }
After the file is fully downloaded, I open the database and add a table to it.
try { myDbHelper.myDataBase.execSQL("CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)"); success = true; } catch (SQLException sqle) { throw sqle; }
Now this code works fine on every device I run it on, but some of my users get this error in the execSQL line. It seems that it does not work only on the Samsung Galaxy SII (there was no complaint and subsequent stacktrace with this error with any other phone), but I'm not entirely sure that this is this phone.
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)
I got a copy of the database downloaded from the user using sgs2 and the file checksum is disabled. I also do not see any data or data structure in the file when opening using the SQL manager (firefox plugin). I let him directly download a copy of the database and put it in my data folder, and the application works fine. So the problem is somewhere in the boot process.