This is the third post in my series about saving data in Android. The other posts can be found here:
A preference is a type of data that needs to be saved by most applications. Preferences allow users to change how the application works by giving choices about things like the layout, the features to enable and the measurement units to use to display data. Default preferences should be good enough for most users, but you may need to offer a choice for more advanced users.
If you must save preferences in your application, the Android SDK includes the Preference
APIs made specifically to store this kind of data. The preferences are saved by the android.content.SharedPreferences
class to an XML file that contains pairs of key-value; the values can be boolean
s, float
s, int
s, long
s or string
s. If you application is uninstalled, all the preferences are also removed since the file is saved to the internal storage of the application. The values for the preferences are saved in clear text, so you should encrypt your data if you want to store sensitive information like credentials.
You can save values directly to the preferences file without user action using the android.content.SharedPreferences
class, but in general users will set their preferences from a Settings window that can be accessed from the action bar of your application. To create the Settings window, the Preference
APIs includes an android.preference.PreferenceFragment
to add to your own activity. This fragment shows a list of preferences and saves the values selected by the user automatically using the android.content.SharedPreferences
class.
Before using the android.preference.PreferenceFragment
, you need to define which preferences will be available from the fragment with a configuration file that is saved to the /res/xml/ folder. Basic preferences types are available from the Android SDK, but you can also create your own custom preference type by overriding the android.preference.Preference
class or one of its sub classes. Here is an example of a preferences.xml file containing an android.preference.CheckboxPreference
, an android.preference.ListPreference
and an android.preference.EditTextPreference
:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:key="welcome_text"
android:title="@string/pref_title_welcome_text"
android:summary="@string/pref_summary_welcome_text"
android:defaultValue="@string/pref_default_welcome_text" />
<ListPreference
android:key="welcome_text_color"
android:title="@string/pref_title_welcome_text_color"
android:summary="@string/pref_summary_welcome_text_color"
android:defaultValue="@string/pref_default_welcome_text_color"
android:entries="@array/colorLabelsArray"
android:entryValues="@array/colorValuesArray" />
<CheckBoxPreference
android:defaultValue="true"
android:key="show_welcome_text"
android:title="@string/pref_title_show_welcome_text"
android:summary="@string/pref_summary_show_welcome_text" />
</PreferenceScreen>
After that, you must use the android.preference.PreferenceFragment
to create your own fragment and specify the configuration to use. Your own fragment can be extended later on if you need to add custom behaviours by implementing the android.content.SharedPreferences.OnSharedPreferenceChangeListener
that is triggered when a preference is modified.
public class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
Finally, to be able to manage your preferences, you must create the activity that hosts the fragment you just defined, which can then be started from another activity by the user.
public class SettingsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment()).commit();
}
}
This is enough to save the preferences to a file automatically, but to do something interesting with the preferences saved, you must retrieve them in your other activities. To get preferences values, you can use the android.content.SharedPreferences
class that is returned by the android.preference.PreferenceManager
for the current context. To complete the previous example, the following code gets the SharedPreferences
object during the onResume
event of the activity and modifies the UI according to the current preferences. The onResume
event is called when the activity starts and when the user comes back from another activity, in that case the SettingsActivity
we created to manage the preferences.
public class MainActivity extends Activity {
@Override
public void onResume() {
super.onResume();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
TextView welcomeTextView = (TextView) findViewById(R.id.hello_world_textview);
String defaultWelcomeText = getResources().getString(R.string.pref_default_welcome_text);
String welcomeText = preferences.getString("welcome_text", defaultWelcomeText);
welcomeTextView.setText(welcomeText);
String defaultWelcomeTextColor = getResources()
.getString(R.string.pref_default_welcome_text_color);
String welcomeTextColor = preferences.getString("welcome_text_color",
defaultWelcomeTextColor);
welcomeTextView.setTextColor(Color.parseColor(welcomeTextColor));
boolean showWelcomeText = preferences.getBoolean("show_welcome_text",
true );
if (showWelcomeText)
welcomeTextView.setVisibility(View.VISIBLE);
else
welcomeTextView.setVisibility(View.INVISIBLE);
}
}
For the complete example that can be executed, see the following GitHub project: http://github.com/CindyPotvin/androidpreferences