Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android SharedPreferences Backup Not Working

I've been doing my homework on how to backup SharedPreferences in my Android application, especially using reflection to maintain backwards compatibility. At least I've been trying. Unfortunately, none of my code actually ends up creating a backup! This includes forcing adb bmgr commands on the emulator as explained here. So I'm wondering if the community could perhaps help me out and in the process come up with some better documentation?

Here's my code. To keep this as generic as possible for others, I will simply call my application Andy with a package name of com.example.andy.

Android Manifest (excerpt)

<application
    ...
    android:backupAgent="com.example.andy.backupHelper"
    android:restoreAnyVersion="true">
    ...
    <meta-data
        android:name="com.google.android.backup.api_key"
        android:value="GIVEN KEY GOES HERE" />
    ...

backupHelper.java

Note: /data/data/com.example.andy/shared_prefs/com.example.andy_preferences.xml

package com.example.andy;

import android.app.backup.BackupAgentHelper;
import android.app.backup.SharedPreferencesBackupHelper;

public class BlinkyBackup extends BackupAgentHelper {

    static final String PREFS_FILE = "andy_preferences";
    static final String BACKUP_KEY = "AndyPreferencesBackup";

    public void onCreate() {

        SharedPreferencesBackupHelper backupHelper = new SharedPreferencesBackupHelper(this, PREFS_FILE);
        addHelper(BACKUP_KEY, backupHelper);
    }
}

BackupAgentWrapper

package com.example.andy;

import android.app.backup.BackupManager;
import android.content.Context;

public class BackupAgentWrapper {

    private BackupManager wrappedInstance;

    static {

        try {

            Class.forName("android.app.backup.BackupManager");
        }
        catch (Exception e) {

            throw new RuntimeException(e);
        }
    }

    public static void checkAvailable() {}

    public void dataChanged() {

        wrappedInstance.dataChanged();
    }

    public BackupAgentWrapper(Context ctx) {

        wrappedInstance = new BackupManager(ctx);
    }
}

And finally, the commands to initiate a backup during run-time. In my application, this code is run from a class available to my application (not the main activity) which is passed this as a context upon creation and then stored in the private variable mContext.

private void backupData() {

    boolean backupAgentAvailable = false;

    try {

        BackupAgentWrapper.checkAvailable();
        backupAgentAvailable = true;
    }
    catch (Throwable t) {

        // really nothing to do
    }

    if(backupAgentAvailable) {

        BackupAgentWrapper backupWrapper = new BackupAgentWrapper(mContext);
        backupWrapper.dataChanged();
    }
}

To summarize, neither the above function nor the commands below actually backup any data:

$ adb shell bmgr enable true
$ adb shell bmgr backup com.example.andy
$ adb shell bmgr run
like image 797
permafrost91 Avatar asked Mar 01 '11 23:03

permafrost91


People also ask

How save and retrieve data using SharedPreferences in Android?

Shared Preferences allow you to save and retrieve data in the form of key,value pair. In order to use shared preferences, you have to call a method getSharedPreferences() that returns a SharedPreference instance pointing to the file that contains the values of preferences.

How much data can we save in SharedPreferences?

There's no hard limit. The main reason it is not recommended to use SharedPreferences in place of the database is mainly the performance -> shared preferences data is keept in ordinary flat XML file which lacks all the features SQLite offers.

Where are Android SharedPreferences stored?

Android stores Shared Preferences settings as XML file in shared_prefs folder under DATA/data/{application package} directory. The DATA folder can be obtained by calling Environment. getDataDirectory() .

Can we store large amount of data in SharedPreferences?

SharedPreferences are not intended to store a lot of data, there is no limit per se (since it is an xml file), but for larger sets of data, I would suggest using Room (or SQLite for the older projects). There is also another reason why storing in a database makes more sense.


1 Answers

In your main calling activity (first one that starts in your app), you need to instantiate BackupManager:

BackupManager mBackupManager = new BackupManager(getApplicationContext());

This will tell the backupmanager to look for the backup file and load it.

You need to make sure the preferences file is format "packagename_preferences" eg. andy_preferences. And use the same name when you first saved your preferences. (Very important!)

After the your settings activity saves via apply() or commit(), you need to tell BackupManager that something has changed so include immediately after:

mBackupManger.dataChanged();
like image 70
Amy Avatar answered Sep 27 '22 19:09

Amy