Android SharedPreferences/PreferenceFragment does not work
I recently researched the section of the Android developer documentation on handling application preferences using shared preferences and PreferenceFragment
and made the following simple example:
SettingsActivity.java
public class SettingsActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState == null)
getFragmentManager().beginTransaction()
.replace(android. R.id.content, new SettingsFragment())
.commit()
}
}
SettingsFragment.java
public class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
res/xml/settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="@string/pref_general_category">
<EditTextPreference
android:key="@id/pref_key_apiBaseUri"
android:title="@string/pref_apiBaseUri_title"
android:defaultValue="@string/pref_apiBaseUri_default"
android:persistent="true"
android:inputType="text"
android:singleLine="true" />
</PreferenceCategory>
</PreferenceScreen>
Other content:
id pref_key_apiBaseUri
string pref_apiBaseUri_title "Api Base Uri"
string pref_api_baseUri_default "http://acme.com/api/
Question
Simple and clear stuff, eh? I launched the app, went to the preferences menu/activity, the preferences fragment was inflated, and I clicked on “API Base Uri“. The EditText
dialog pops up, I change “http://acme.com/api
” to “http://acme.com/api2
” and press OK. Now, as far as I understand the documentation, preferences should be automatically saved to sharing preferences. When I reopen the EditText
dialog, I see that my changes have been saved.
But…… When I close the activity (or application) and go back to the settings, the default value is back with no changes! What do I do to save my settings permanently?
Solution
In your settings.xml, you have:
<EditTextPreference
android:key="@id/pref_key_apiBaseUri"
android:title="@string/pref_apiBaseUri_title"
android:defaultValue="@string/pref_apiBaseUri_default"
android:persistent="true"
android:inputType="text"
android:singleLine="true" />
You must specify a string for key, as described in the documentation for android:key:
This attribute is required for preferences that persist a data value. It specifies the unique key (a string) the system uses when saving this setting’s value in the SharedPreferences.
Your pref_key_apiBaseUri appears to be an empty string. Change it to a valid string and move to strings.xml:
<string name="pref_key_apiBaseUri">KEY</string>
Then used as:
<EditTextPreference
android:key="@string/pref_key_apiBaseUri"
...
Or leave it as is, just add a +
before the id tag, which will create the id, which in turn will be used as the key:
<EditTextPreference
android:key="@+id/pref_key_apiBaseUri"
...