Preloaded database corruption issue in Android application

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.

+4
source share
3 answers

Starting with API level 9 (Android 2.3), you can use the DownloadManager to handle long HTTP downloads:

Download Manager is a system service that handles lengthy HTTP downloads. Clients may request that the URI be loaded into a specific destination file. The download manager will conduct downloads in the background, taking care of HTTP interactions and reloading downloads after failures or changes in connectivity and rebooting the system.

Here is an example project demonstrating the use of DownloadManager: Android Downloader download example .

I think you can even try to backup DownloadManager to previous versions of Android (if you need to support them). Its source code can be found here: DownloadManager.java

+1
source

Do you call a flash and close your output stream? Like this:

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

If not for me, I would start with this. I downloaded a video with a similar code and found that for some devices and some videos that do not cause flash, it is distorted and makes it unplayable

+1
source

Here's another question that talks about this type of Android database corruption - the database disk image is distorted .

If you cannot fix the database when it is in this state, you may try to load it again if and when this error occurs (it is assumed that this problem is rare and loading the database can solve the problem again).

0
source

All Articles