2

i am having the same problem as this thread, default values are not being initialized for preferences,

i have 2 preference.xml files

this is the onCreate on my main activity:

protected void onCreate(Bundle savedInstanceState) {
    PreferenceManager.setDefaultValues(this,R.xml.preference,false);
    PreferenceManager.setDefaultValues(this,R.xml.other_preference,false);//this doesn't work now because of the previous row
    String value = PreferenceManager.getDefaultSharedPreferences(this).getString("pref_from_other_preference", null); //this returns null
}

my problem is that if i set readAgain as false (so it doesn't overwrite user selected preference) only the first call to this method is being performed.

how do i set default values for all my preference xml's?

EDIT:i tried a "hack" for a solution, which is to try and fetch a value that has a default value and if its null, call getDefaultSharedPreferences with readAgain as true. and it did not work (only the first call initialized its values)

Community
  • 1
  • 1
user1333057
  • 607
  • 1
  • 8
  • 19

4 Answers4

1

You can delete keys which should be reset to the default values and when call the method PreferenceManager.setDefaultValues(). So these keys will be created with default values.

sharedPreferencesEditor= PreferenceManager.getDefaultSharedPreferences(context).edit();
//this delete myPrefKey key
sharedPreferencesEditor.remove("myPrefKey").commit();

//this creates keys which didn't exist with defaul values.
//myPrefKey isn't exist so it will be created
PreferenceManager.setDefaultValues(this,R.xml.preference,false);
Alex78191
  • 2,383
  • 2
  • 17
  • 24
1

I believe this is some kind of bug in the framework. If you look into the code you will see that the first call to PreferenceManager.setDefaultValues sets KEY_HAS_SET_DEFAULT_VALUES to true. After this, any other call to PreferenceManager.setDefaultValues will be ignored unless you set readAgain to true.

This one single shot flag contradicts the fact that we now need to create separate XML files, one for each settings fragment. And call this method multiple times, as you're doing. I still haven't figured out a workaround for it. Therefore the only solution for now is to always call with readAgain set to true.

By the way, this is the only purpose of the parameter readAgain. Once a setting has been stored, the value cannot be changed by the method PreferenceManager.setDefaultValues, even if you set readAgain to true. If you want to change the value when calling this method then you need to first clear the stored values.

Héctor Júdez Sapena
  • 5,329
  • 3
  • 23
  • 31
1

The method PreferenceManager.setDefaultValues(...) basically stores a boolean key KEY_HAS_SET_DEFAULT_VALUES ( = "_has_set_default_values") in a separate SharedPreferences file of the same name after setting defaultValues from the specified xml.

So here's my work around -

@Override
    protected void onCreate (@Nullable Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setDefaults();

    //.......
}
    private void setDefaults () {
    //This will check if defaults have been set ever before
    if (!getSharedPreferences(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE)
            .getBoolean(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, false)) {

        PreferenceManager.setDefaultValues(this, R.xml.preferences, true);
        PreferenceManager.setDefaultValues(this, R.xml.other_preference1, true);
        PreferenceManager.setDefaultValues(this, R.xml.other_preference2, true);

    }
}

Checking KEY_HAS_SET_DEFAULT_VALUES value before calling this method makes sure this method is called only on the first app launch. But As Héctor Júdez Sapena pointed out, once a value has been set, this method is not effective. So, always calling with readAgain = true wont hurt either.

To reset all the preferences to default -

PreferenceManager.getDefaultSharedPreferences(context).edit().clear().apply();
PreferenceManager.setDefaultValues(context, R.xml.preferences, true);
PreferenceManager.setDefaultValues(context, R.xml.other_preference1, true);
PreferenceManager.setDefaultValues(context, R.xml.other_preference2, true);

or

PreferenceManager.getDefaultSharedPreferences(context).edit().clear().apply();
context.getSharedPreferences(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE)
                .edit()
                .putBoolean(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, false)
                .apply();
//restart application 

Note that here we're only working on Default SharedPreferences file. If you have multiple SharedPreferences files then you need to call this for each of them.

0

Notice what the docs for this method say:

Note: this will NOT reset preferences back to their default values. For that functionality, use getDefaultSharedPreferences(Context) and clear it followed by a call to this method with this parameter set to true.

So you need to clear all preferences from your default preferences manager in order to make use of this method. I don't use this method at all when resetting my preferences (because I only need to reset a subset of preferences, not all of them). Instead I set the values of preferences which I intend to reset to null. I also use the second argument in SharedPreferences.getXXX methods to pass the default value that becomes available the moment I set the preference to null.

For example,

Default resource:

<bool name="myPrefDefault">true</bool>

Preference:

<CheckBoxPreference
    android:key="myPrefKey"
    android:title="My Pref Title"
    android:summary="My Pref Summary"
    android:defaultValue="@bool/myPrefDefault" />

Java:

//this returns whatever preference was set for myPrefKey in PreferencesPage or the default value if nothing was set
sharedPreferences.getBoolean("myPrefKey", getResources().getBoolean(R.bool.myPrefDefault));

//this effectively resets the myPrefKey to its default value
sharedPreferences.edit().remove("myPrefKey").commit();