I'm use Android ICS SDK and I would like to do a PreferenceScreen which use MultiSelectListPreference (avalaible for API Level 11&+.
I just want to persist the value in SharedPref, refresh the summary of the MultiSelectListPreference and refresh the dialog list.
Here's my code :
Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.newgame);
mMultiCharacters.setOnPreferenceChangeListener(this);
}
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor settingsEditor = settings.edit();
settingsEditor.putStringSet( preference.getKey() , (Set<String>) newValue);
settingsEditor.commit();
//display new summary
initChar();
return false;
}
XML part :
<MultiSelectListPreference
android:entries="#array/characterNames"
android:entryValues="#array/characterNames"
android:key="pref_characters"
android:persistent="true"
android:title="Chars :" />
The behavior is quite strange. The dialog list doesn't refresh… some ideas ? Thanks!
Well.. I used MultiSelectListPreference once, and here is what I "think" ..
You are returning false in the onPreferenceChange listener, which I think it doesn't only NOT commit the changes, but also may be reverting to the previous values. I'm aware that you are committing the changes through settingsEditor but may be the false return is reverting back the old values, so I suggest returning true.
One more thing, the newValue object is actually a HashSet which contains the newly selected values, so you can use it to do whatever you want but you don't have to use it to commit changes if you are returning true.
Good Luck.
Related
In my app I was using for more than 1 year "Shared preferences" to store some boolean values (if the user has seen the intro page for example). Now I added one more setting (if the user has seen the help page!) and all the settings stopped working...
I tried changing "commit" to "apply" with no luck. How could by just adding one more shared preference to make it stop working? Is there any properties limit?
My code:
public SharedPreferences getSettings() {
SharedPreferences settings = getSharedPreferences(AppConstants.PREFS_NAME, 0);
return settings;
}
old Activity for Intro:
private void saveUserHasSeenIntro() {
SharedPreferences.Editor editor = getSettings().edit();
editor.putBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_INTRO_STEPS, true);
editor.commit();
}
where intro boolean is being read:
Boolean hasShownIntroSteps = getSettings().getBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_INTRO_STEPS, false);
if ( !hasShownIntroSteps ) {
// show intro
} else {
New activity for help:
private void saveUserHasSeenHelp() {
SharedPreferences.Editor editor = getSettings().edit();
editor.putBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, true);
editor.commit();
}
where the "help" boolean is read:
Boolean hasSeenHelp = getSettings().getBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, false);
if ( !hasSeenHelp ) {
// show help activity
} else {
Your methods are fine and they should work perfectly. Check a couple of things just in case:
Ensure you don't call clear() or remove() method of the SharedPreferences editor after saving your prefs by mistake.
Ensure the constants AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS and AppConstants.SETTING_BOOLEAN_HAS_SHOWN_INTRO_STEPS have different values as the former could overlap the second by mistake.
Just add a breakpoint after setting the new pref and read the value to check if it's set just after it.
SharedPreferences.Editor editor = getSettings().edit();
editor.putBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, true);
editor.commit();
Boolean hasSeenHelp = getSettings().getBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, false);
In some extreme cases you could even implement SharedPreferences.OnSharedPreferenceChangeListener to see where your SharedPreferences are being changed to avoid unwanted pref sets.
It can be a Memory Limitation on your SharedPreferences file and usually this comes with an OutOfMemoryException. I guess if something like that would happen you would probably seen it in your code, unless you are not reading/writing in another Thread. How big is your SharedPreferences file in numbers of key - value pair ?
In Android 4, I have a preference value that I want to appear in the standard form E2C56DB5-DFFB-48D2-B060-D0F5A71096E0. But the user may enter the value without dashes. I would like to allow the user to enter it with any combination of whitespace or dashes, and simply have my code normalize it.
I am using the code below, and I see the log line, but it does nothing. I am guessing this is because Android has another Editor object open that overwrites my changes. Is there any other way to accomplish this?
public class UuidFragment extends PreferenceFragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
this.getPreferenceScreen().findPreference("pref_uuid").setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
if (newValue.toString().length() != 0) {
String normalizedUuid=normalizeUuid(newValue.toString());
// TODO: this code runs but does nothing, I think because after committing the change, there is a higher level editor that commits the old value
// thereby undoing this change
if (!normalizedUuid.equals(newValue.toString())) {
Log.d(TAG, "Adjusting uuid from "+newValue.toString()+" to "+normalizedUuid);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(UuidFragment.this.getActivity());
SharedPreferences.Editor editor = settings.edit();
editor.putString(preference.getKey(), normalizedUuid);
editor.commit();
}
return true;
}
}
});
}
}
Try subclassing EditTextPreference and overriding setText(). In your setText() method, fix up the passed-in string before chaining to the superclass. Then, reference your EditTextPreference subclass from your preference XML.
I have in my main activity access to a shared preference like this:
preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("maxValue", "666");
Boolean test = editor.commit();
when I open my Preference activity I see for that preference the value 666. So that works without issue.
Now I want to do pretty much the same in my Preferences.java, background is that I want to check the input string and notify the user if something is wrong, e.g. I want to make sure that if the users sets the maxValue above 1000, to tell him that this is too high and set it to 899 automatically. I have implemented a change listener:
#Override
public boolean onPreferenceChange(Preference pref, Object newValue)
{
if(Integer.valueOf(etAdd.getEditText().getText().toString()) > 899)
{
SharedPreferences.Editor editor = preferences.edit();
editor.putString("maxValue", "899");
Boolean test = editor.commit(); //test shows true
Toast.makeText(Preferences.this, "value too high have set it to the maximum of 899", Toast.LENGTH_LONG).show(); //this toast is shown
}
return true;
}
When I re-open this preference, even after leaving the preference activity and returning back to it, I see the value the user has entered, e.g. 1000.
anyone an idea?
thanks.
According to the documentation onPreferenceChange is called BEFORE the changes are written. If you return true (accept new Value), after leaving onPreferenceChange the newValue object is successfully applied and your modifications are ignored. That is the reason of mentioned behavior. Returning false would do the trick.
To project your corrected value to PreferenceActivity immediately, use SetText on your EditTextPreference.
Using typecasted newValue.toString() instead of using contents of the corresponding EditText is also worth considering.
I'ma a bit confused here. I'm trying to change the value of an EditTextPreference, but it is not updated in the view. (This is in a PreferenceActivity)
Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.modify_instrument_preferences);
// Set default values
SharedPreferences customSharedPreference = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = customSharedPreference.edit();
modifying = getObjectWithName(); //Some object with a name;
editor.putString("namePref", modifying.getName());
editor.commit();
android.util.Log.d("TEST", "written: "+customSharedPreference.getString("namePref",""));
}
My printlns print out valid information, and the commit() returns true, but on clicking the EditTextPreference, it displays the old value. If I rotate the screen, causing the onCreate to get run again, the EditTextPreference has the right value.
So perplexing. Why isn't this change being updated in the UI?
Edit:
I'm not sure why the above isn't working, but I managed to change it just by doing:
EditTextPreference namePref = (EditTextPreference) findPreference("namePref");
namePref.setText("the text");
That updated the view everytime.
Although I know there are some constructs in place for PreferenceActivities to keep track of this info themselves, it doesn't seem to be well documented. I have found that adding an onPreferenceChangeListener to the preference will allow you to make those edits as soon as the preference is changed.
I use a Preference in a PreferenceActivity to load default values: when this specific Preference is clicked, something like this happens:
private String mResetKeys = "key1,key2,key3";
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor prefs_editor = prefs.edit();
for (String current_pref : mResetKeys.split(",")) {
prefs_editor.remove(current_pref);
}
prefs_editor.commit();
But afterwards, the Preferences whose corresponding SharedPreference was reset still show the old value - it seems to be cached in the Preference. Only when I leave the PreferenceActivity and reopen it, the Preferences show the new values.
How can I update the PreferenceActivity programmatically?
I had a similar problem. This probably isn't the most correct fix but it worked for my purposes. Right after I did the commits, I called the Activity.recreate(); method.
The activity will restart (onDestroy()/onCreate()/etc) but for my purposes all I needed was a special handling on one preference. I listened for a certain preference with an OnPreferenceClickListener and made an alert dialog box with a kind of warning message and an option to change their mind. If they did want to change their mind, I did my commit of the new value to the preference activity and then called recreate() so that the checkbox preference would be updated.
However, I am also interested in a way to do this without recreating the activity...
Update preference value without reloading PreferenceActivity
from http://liquidlabs.ca/2011/08/25/update-preference-value-without-reloading-preferenceactivity/
Here is how to update default shared preference value of target element (in this case EditTextPreference)
public class YourCustomPreference extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
// some logic goes above, when you want to reset value and update EditTextPreference value
// For convenience, I am going to wrap two different task in different methods
private void resetPreferenceValue() {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
SharedPreferences.Editor prefEditor = sharedPref.edit(); // Get preference in editor mode
prefEditor.putString("your_edit_text_pref_key", "DEFAULT-VALUE"); // set your default value here (could be empty as well)
prefEditor.commit(); // finally save changes
// Now we have updated shared preference value, but in activity it still hold the old value
this.resetElementValue();
}
private void resetElementValue() {
// First get reference to edit-text view elements
EditTextPreference myPrefText = (EditTextPreference) super.findPreference("your_edit_text_pref_key");
// Now, manually update it's value to default/empty
myPrefText.setText("DEFAULT-VALUE"); // Now, if you click on the item, you'll see the value you've just set here
}
}