Для большинства приложений требуется сохранить настройки, управляющие поведением программы. Android предоставляет несколько альтернативных способов сохранения данных приложения, каждый из которых оптимизирован для определенных нужд.
Общие настройки — простой и легкий механизм, основанный на парах «ключ — значение» и предназначенный для сохранения примитивных данных приложения, чаще всего пользовательских настроек.
Введение
Класс SharedPreferences позволяет создавать в приложении именованные ассоциативные массивы типа «ключ — значение», которые могут быть использованы различными компонентами приложения (работая при этом в контексте одного и того же приложения).
Общие настройки поддерживают базовые типы boolean, string, float, long и integer, что делает их идеальным средством для быстрого сохранения значений по умолчанию, переменных экземпляра класса, текущего состояния UI и пользовательских настроек.
Создание и сохранение настроек
Чтобы создать или изменить Общие настройки, нужно вызвать метод
getSharedPreferences
в контексте приложения, передавая имя общих настроек, которые вы хотите изменить. Настройки недоступны для других приложений.
public static String MY_PREF = "MY_PREF"; protected void savePreferences() { // получить доступ к объекту Editor, чтобы изменить общие настройки. SharedPreferences.Editor editor = mySharedPreferences.edit(); // задать новые базовые типы в объекте общих настроек. editor.putBoolean("isTrue", true); editor.putFloat("floatNumber", 1f); editor.putInt("intNumber", 2); editor.putLong("longNumber", 3l); editor.putString("textValue", "Not Empty"); editor.commit(); }
Получение общих настроек
Надо передать в getSharedPreferences
имя тех общих настроек, доступ к которым хотите получить, и используйте типизированный метод get<тип>, чтобы извлечь сохраненные значения. Передаются ключ и значение по умолчанию (используется случае, если для данного ключа пока что не сохранено никакое значение).
public static String MY_PREF = "MY_PREF"; public void loadPreferences() { int mode = Activity.MODE_PRIVATE; SharedPreferences mySharedPreferences = getSharedPreferences(MY_PREF, mode); boolean isTrue = mySharedPreferences.getBoolean("isTrue", false); float lastFloat = mySharedPreferences.getFloat("floatNumber", 0f); int wholeNumber = mySharedPreferences.getInt("intNumber", 1); long aNumber = mySharedPreferences.getLong("longNumber", 0); String stringPreference = mySharedPreferences.getString("textValue", ""); }
Очистка/удаление значения
Для очистки значений используйте методы SharedPreferences.Editor.remove(String key)
и SharedPreferences.Editor.clear()
.
Файл настроек хранится в /data/data/package_name/shared_prefs/имя_файла_настроек.xml. Можно удалить:
File file= new File("/data/data/.../shared_prefs/файл_настроек.xml") file.delete();
Preferences Framework
В примерах выше происходило обычное сохранение и восстанавлениеи нужных параметров. То есть, создаётся свой xml-файл разметки и размещаются там нужные элементы управления. Но Android для этих целей предоставляет собственный Preferences Framework, с помощью которого можно создавать индивидуальный набор предпочтений и встраивать их в приложения.
То есть, теперь нет необходимости создавать файл разметки и get/set параметров писать самим. Необходимо лишь в отдельном файле перечислить параметры, а Android уже остальное сделает. Предпочтения — это отдельная активность в приложении, вызываемая из активности. Сам Activity расширяется от класса PreferenceActivity
. Предпочтения определяются в отдельном XML-файле, где корневым элементом является элемент <PreferenceScreen>
, который представляет собой контейнер для предпочтений и может содержать дочерние элементы <PreferenceScreen>
. Элемент <PreferenceCategory>
также является контейнерным элементом и предназначен для объединения предпочтений в группы.
PreferenceScreen
Необходимо первоначально создать в папке res/xml/ XML-файл ресурсов, как например, settings.xml. Выбирайте тип файла Android XML File:
При создании файла в диалоговом окне установите переключатель на Preference и убедитесь, что корневым элементом файла установлен PreferenceScreen:
settings.xml
Далее задаём необходимые настройки:
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory android:title="@string/interface_settings"> <EditTextPreference android:key="pref_size" android:title="@string/interface_settings_pref_size" android:summary="@string/interface_settings_set_new_fsize" android:defaultValue="14" android:dialogTitle="@string/interface_settings_enter_fsize" /> <ListPreference android:key="pref_lng" android:title="@string/interface_settings_language" android:summary="@string/interface_settings_set_language" android:defaultValue="1" android:entries="@array/lng_list" android:entryValues="@array/entryvalues_lng" android:dialogTitle="@string/interface_settings_check_language" /> </PreferenceCategory> </PreferenceScreen>
Мы определили две настройки: размер шрифта, язык приложения. С <EditTextPreference>
всё в целом понятно, простое поле. А вот для выбора языка посложнее элемент. Нас тут интересует 2 поля: android:entries
и android:entryValues
. Из названия, думаю, понятно их назначение.
Определение параметров в string.xml и array.xml
Естественно, необходимо определить все переменные. В string.xml:
<resources> <string name="pref_lng">Стиль</string> <string name="pref_size">Размер</string> <string name="interface_settings">Настройки интерфейса</string> <string name="interface_settings_pref_size">Размер шрифта</string> <string name="interface_settings_set_new_fsize">Устанавливает новый размер шрифта</string> <string name="interface_settings_enter_fsize">Введите размер шрифта (от 10 до 32)</string> <string name="interface_settings_language">Язык приложения</string> <string name="interface_settings_set_language">Устанавливает стиль для шрифта</string> <string name="interface_settings_check_language">Выберите язык</string> <string name="title_activity_settings">Настройки</string> </resources>
А так же в array.xml:
<resources> <string-array name="lng_list"> <item>Язык аппарата</item> <item>English</item> <item>Русский</item> </string-array> <string-array name="entryvalues_lng"> <item>default</item> <item>en</item> <item>ru</item> </string-array> </resources>
PreferenceActivity
Для PreferenceActivity
автоматически создаётся SettingsActivity
. Нам в нём слегка необходимо изменить метод onCreate
.
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); }
Метод addPreferencesFromResource()
считывает установленные настройки из XML-файла, где хранятся наши ресурсы, и делает их доступными для программы. В результате мы должны увидеть настройки на экране. Если автоматически наше Activity не было зарегестрировано, то добавим в манифесте AndroidManifest.xml:
<activity android:name=".SettingsActivity" android:label="@string/title_activity_settings" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="android.preference.PreferenceActivity" /> </activity>
Ну и напишем код, чтобы при клике на меню, открывалось наше окно с настройками. Для этого определим метод по созданию меню и onCreateOptionsMenu
и метод, отслеживающий нажатия по меню onOptionsItemSelected
:
public static final int IDM_PREF = 101; @Override public boolean onCreateOptionsMenu(Menu menu ) { menu.add(0, IDM_PREF, 0, "Настройки"); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { Intent intent = new Intent(); switch (item.getItemId()) { case IDM_PREF: intent.setClass(this, SettingsActivity.class); startActivity(intent); break; } }
Теперь при вызове меню опций, нажимайте на пункт «Настройки» и откроется наше окно настроек.
Для сохранения предпочтений на выбор есть 4 класса:
- CheckBoxPreference
- EditTextPreference
- ListPreference
- RingtonePreference
Конкретно в данном примере используется EditTextPreference и ListPreference.
Так выглядит окно изменения для настроек:
Отслеживание изменений в общих настройках
Класс onSharedPreferenceChangeListener
позволяет вызвать callback-метод в момент добавления, удаления или изменения конкретной Общей настройки. Используя этот обработчик, компоненты вашего приложения могут следить за изменениями в настройках, установленных пользователем, и обновлять пользовательский интерфейс или корректировать поведение программы.
This function is not relevant for a modern fragment-based PreferenceActivity
This function is not relevant for a modern fragment-based PreferenceActivity. Inflates the given XML resource and adds the preference hierarchy to the current preference hierarchy.
Такое сообщение вы увидите в SDK по поводу многих методов PreferenceActivity
, у того же addPreferencesFromResource
. Это означает, что методы устарели. В сущности, ничего фатального в этом нет, просто в более поздних версиях появились более удобные методы.
С версии 3.0 появились так называемые Fragments, с помощью которых можно работать с настройками.
Ещё раз повторю, если у вас старый вариант для работы с настройками используется, то он будет работать на всех устройствах нормально. Но если вы пишите для устройств с версией Android 3+, то лучше используйте фрагменты.