1

I've got an app that allows the user to save the app SQLite database files to the SD card. This function has been in place for over a year and has worked just fine. I've had users email me their database files in cases where there was an error that I could not reproduce.

Recently, a user sent me his database files, and when I tried to load them into my app (by placing them into the app's database file location), the app crashed when trying to open the database file. This user has sent me his files before in the past with no problems.

The only differences between my app back then and now are: 1) I added app-2-SD functionality, and 2) My app targets 2.2 now versus 1.6 back then (but 1.5 is the min SDK version in both cases).

The user said he placed the app on the SD card and then the app started crashing. It doesn't even give him the option of submitting an error report.

When I placed his files in the emulator, I got the following stack trace:

11-09 22:32:04.275: ERROR/AndroidRuntime(757): Caused by: android.database.sqlite.SQLiteException: file is encrypted or is not a database
11-09 22:32:04.275: ERROR/AndroidRuntime(757):     at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
11-09 22:32:04.275: ERROR/AndroidRuntime(757):     at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1636)
11-09 22:32:04.275: ERROR/AndroidRuntime(757):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1586)
11-09 22:32:04.275: ERROR/AndroidRuntime(757):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:638)
11-09 22:32:04.275: ERROR/AndroidRuntime(757):     at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:168)

He's emailed me the data before, and the files had the correct database name and extension, so I'm giving him the benefit of the doubt and not assuming he sent an incorrect file. Has anyone seen this problem before, and know of any possible causes and/or solutions?

Update In case it makes any difference, I found out from the user that his phone is an HTC Evo 4G. I thought I read something somewhere about encrypted database files in more recent Android releases, where the database files are stored under /data/secure/... rather than /data/data/... I wonder if this could be related? In any case, after questioning the user further, I at least know that it is one specific table in the database file that is having a problem. Different parts of my app interact with different tables within the database file. The app works fine, and allows him to save/read data when he accesses the other tables, but when he accesses one particular table, just trying to open the file produces his error. I'm thinking I can add an ugly fix that catches this exception if it occurs and then drop the corrupted table and then recreate it. Thoughts?

Michael
  • 648
  • 11
  • 23
  • Ok, Can you check this file using any tool of SQLite, try to open this database file in SQLite tool and see are you getting correct data in it. – user370305 Nov 10 '11 at 06:57
  • That's exactly the first thing I tried. When I opened the file in SQLite, there was nothing there. It didn't show my tables, how the tables where constructed, etc... Nothing was in the file, even though the file was not 0 bytes. – Michael Nov 10 '11 at 15:33
  • @Michael I also get this issue like this. Do you have find the solution? My question is http://stackoverflow.com/questions/10210503/database-disk-image-is-malformed-or-file-is-encrypted-or-is-not-a-database. – Judy Apr 19 '12 at 01:49
  • I don't have a true answer. I *THINK* the problem is related to the database being left open when transitioning from one Activity to another. I had an activity where a save would be performed on the SQLite database, and my intention was to close the database once the save was completed. However, I found an error condition that allowed the save to take place, but prevented the database from being closed. Then the app would jump to another Activity that also accessed the database. After I fixed that error, I haven't had any more corruption problems, but I can't confirm this was the cause. – Michael Apr 22 '12 at 01:50

1 Answers1

0

I also have an app with a (rather small) db and recently I get crash reports due to db problems that I could not reproduce.

Playing around with my app and really pushing it finally caused crashes.

The reason in my case was that due to many fast opening/closing/update requests, interruption of the app, language changes during the app, etc so the system somehow corrupted the db.

The solution I implemented now is

a. close/reopen the db often to avoid problems 

b. have a consistency-check routine for every save or retrieve of data now - lots of overhead - but that cleared it fo me so far...

ps I did not get the same crash report though as yours. I have now a couple of different Android phones on my desk for testing now and almost never got it to crash with the newest high-end ones. Those problems seem to happen more often with smaller memory/slower speed cpu phones than with fast high-end ones. - but honestly I am still confused about this! ... possibly the SD-card use is related to that too somehow?

user387184
  • 10,953
  • 12
  • 77
  • 147
  • Thanks. I do close/reopen the database each time I need access, but I don't have a consistency check in place. I'll need to look into that. How did you setup your checks? Something along the lines of wrapping try-catch blocks around database open/save statements, and alerting the user of problems if an exception is caught? Or something much deeper? – Michael Nov 10 '11 at 18:06
  • I use try-catch with consistency checks to ensure that there is no invalid data. If I happen to find invaid data I use certain default values to replace the invalid values. In my case that's possible and I do not have to inform the user. He might just be surprised that some stored values are lost - but that can be forgiven. By the way I have to duplicate the same code for this in all my activities so they can easily react in these cases - however, this might not be the best approach.. Good luck - again - nobody really knows if this is the solution, unfortunately – user387184 Nov 11 '11 at 16:32