Home » Android » android – Refresh/Reload database reference in custom ContentProvider after restore

android – Refresh/Reload database reference in custom ContentProvider after restore

Posted by: admin June 15, 2020 Leave a comment

Questions:

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?

How to&Answers:

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!

Answer:

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);
}

Answer:

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.

Answer:

You can also simply use the delete method without a selection:

context.getContentResolver().delete(YourProvider.CONTENT_URI, null, null);