Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refresh/Reload database reference in custom ContentProvider after restore

I use a ContentProvider in my app and everything works great except for one little issue. I have a backup and restore function that backs up the database to a file on the SD card and then those backup files can be restored to overwrite the current database. This whole process is working, but the ContentProvider still holds the reference/cache to the original database once one of the old backup files is restored. I can't seem to find a way to refresh or reload the database reference in the ContentProvider. I know the restore works because I can see the records in the db with SQLite Editor and when I close and re-open the app, it displays the correct records.

Does anybody know a way to do this? Is there a way to close and re-open the ContentProvider that I'm not seeing?

like image 845
ssuperz28 Avatar asked Nov 22 '11 23:11

ssuperz28


3 Answers

If you are targeting >= API 5 you can get a reference to your ContentProvider via a ContentProviderClient, and run a method specific to your implementation:

ContentResolver resolver = context.getContentResolver();
ContentProviderClient client = resolver.acquireContentProviderClient("myAuthority");
MyContentProvider provider = (MyContentProvider) client.getLocalContentProvider();
provider.resetDatabase();
client.release();

Add the reset method to your ContentProvider implementation:

public void resetDatabase() {
    mDatabaseHelper.close();
    mDatabaseHelper = new MyDatabaseOpenHelper(context);
}
like image 156
ptc Avatar answered Nov 20 '22 20:11

ptc


Are you maintaining a reference to the actual SQLiteDatabase in your content provider (something like calling SQLiteOpenHelper.getWritableDatabase() in onCreate() and then keeping that reference)? Or do you get the DB object from someplace like a helper in each provider method?

Typically, if you only keep a local reference to the helper and get the writable/readable database instance inside of each method as needed then this problem should go away. If not, perhaps we can take a look at the provider code?

Hope that Helps!

like image 32
devunwired Avatar answered Nov 20 '22 19:11

devunwired


Here is my solution.

public class DataProvider extends ContentProvider {

    private DataDbHelper dbHelper;

    @Override
    public boolean onCreate() {
        // nothing here
        return true;
    }

    private DataDbHelper getDbHelper() {
        if (dbHelper== null) {
            // initialize
            dbHelper = new DataDbHelper(getContext());
        } else if (dbHelper.getReadableDatabase().getVersion() != DataDbHelper.VERSION) {
            // reset
            dbHelper.close();
            dbHelper = new DataDbHelper(getContext());
        }
        return this.mOpenHelper;
    }
}

query(), insert(), update(), delete() use getDbHelper() to obtain an SQLiteDatabase

The full code of my Android app is available here if you need more info.

like image 22
mmathieum Avatar answered Nov 20 '22 19:11

mmathieum