When it comes to Android application development, it’s often desirable to ensure the app is compatible with older versions of the Android OS. A customer has recently asked us to make an application while keeping backward compatibility down to SDK version 2.1 (API level 7). While working on that project, we encountered a problem: the built-in SQLite version 3.5.9 had a known bug that appeared under certain conditions. Incidentally, SQLite caused the application to crash due to a "database disk image is malformed" error and the entire database was rendered unusable. We didn't find a solution for this problem on the web, so we created the following workaround after some experimenting.
So, what should you do if you’ve stumbled upon this bug? Wrap database access into a content provider. The rest of this post gives step-by-step instructions on how to implement it in your own project.
1. Leave SQLiteOpenHelper untouched. We'll use it later.
2. Create a content provider by subclassing android.content.ContentProvider. Next, you'll need to implement several methods, namely insert, update, delete и query. The implementation is going to be simple: parse the URI and use SQLiteOpenHelper to do the real work. Our code throws a couple of exceptions: SQLiteException and NullPointerException. Make sure you catch them - they might happen if the SD card is malfunctioning or it is out of free space.
3. Add the following lines to AndroidManifest.xml:
<provider android:name="com.somecompany.database.DatabaseProvider" android:authorities="com.somecompany" android:exported="false">
Note the android:exported attribute. It is used to limit access to the data provider for other applications.
4. It is convenient to take the entire URI creation and access to the underlying implementation to a higher level. The content provider will be created by the platform and work as a black box from this point:
context.getContentResolver().insert( "content://" + "com.somecompany" + "someTable", contentValues);
Adding a content provider proved to be a nice workaround for the problem and we successfully completed the project. If you'd like to learn more about ContentProvider and accessing databases, developer.android.com is the best source of information on the subject.