Настройки Android: как загрузить значения по умолчанию, когда пользователь не использовал экран настроек?

119

Я использую PreferenceActivity, чтобы пользователь мог устанавливать некоторые значения. Я скармливаю ему XML-файл с определенными настройками.

Я установил android:defaultValue=""для них все.

Когда я запускаю свое приложение, мне нужны настройки или, если они еще не установлены вручную, мне нужны значения по умолчанию:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean value = prefs.getBoolean("key"), false); 

Однако когда android:defaultValue="true"я все же получу false. Итак, похоже, что значения по умолчанию, установленные в XML, нигде не используются, кроме как при инициализации экрана настроек.

Я не хочу жестко кодировать значения по умолчанию в getBoolean()методе. Итак, есть ли способ получить значения по умолчанию, определив их только в одном месте?

Peterdk
источник

Ответы:

169

этот вопрос похож на мой:

Инициализировать-предпочтения-из-XML-в-основной-деятельности

Просто используйте этот код в onCreateметоде:

PreferenceManager.setDefaultValues(this, R.xml.preference, false);

Он загрузит ваши предпочтения из XML, а последний параметр ( readAgain) гарантирует, что предпочтения пользователя не будут перезаписаны. Это означает, что установка readAgainаргумента falseозначает, что это будет устанавливать значения по умолчанию только в том случае, если этот метод никогда не вызывался в прошлом, поэтому вам не нужно беспокоиться о переопределении настроек пользователя каждый раз, когда создается ваша Activity.

Взгляните на PreferenceManager.setDefaultValues в Android API для дальнейшего изучения.

пиксель
источник
Можем ли мы использовать это поверх любой другой создаваемой нами переменной SharedPrefrence?
Амол Гупта
8
Кроме того, если ваше приложение имеет несколько точек входа, поместите его в onCreate()оф Application.
SD
2
Это не работает, если используется логическое значение и по умолчанию установлено значение «false», поскольку тогда запись по умолчанию не будет создана в Android 2.x. Вызов ".getBoolean (KEY, true)" всегда будет возвращать истину. Для Android 4.x работает.
Gunnar Bernstein
10
Значение readAgaintrue не имеет ничего общего с перезаписью пользовательских настроек. Из Javadoc: Примечание: это НЕ сбросит настройки до значений по умолчанию.
devconsole 02
1
Для тех, у кого есть проблемы с этим решением (оно не работает или работает частично или не всегда), см. Ответ Стива Уоринга ниже ( stackoverflow.com/a/25602205/4410376 ). Скорее всего, у вас есть несколько файлов shared-prefs, т.е. android создает несколько файлов shared-prefs на основе вашей конфигурации или беспорядочного кода.
Hack06,
27

Имейте в виду, что если вы используете
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

чтобы получить настройки, которые вы должны использовать для установки значений по умолчанию!
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

Например:
PreferenceManager.setDefaultValues(this, PREFS_NAME, Context.MODE_PRIVATE, R.xml.preference, false);

Надеюсь, это кому-то поможет.

Франческо Вадикамо
источник
13

в принятом ответе Pixel:

PreferenceManager.setDefaultValues(this, R.xml.preference, false);

заявлено, что это falseозначает, что значения по умолчанию не будут перезаписаны. Это не то, что он делает, это просто флаг эффективности, позволяющий остановить синтаксический анализ, если ваше приложение имеет более одной точки входа. К сожалению, тест проводится не для каждого файла предпочтений, поэтому, если у вас более одного файла предпочтений, вы должны кодировать trueвсе, кроме первого.

Если вас беспокоит эффективность, вы можете написать что-то вроде этого.

final static private int SPL = 1;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (sp.getInt("spl", 0) != SPL)
{
    PreferenceManager.setDefaultValues(this, R.xml.prefs1, true);
    PreferenceManager.setDefaultValues(this, R.xml.prefs2, true);
    sp.edit().putInt("spl", SPL).apply();
}

Если вы когда-нибудь добавите больше общих предпочтений, просто установите SPL на высокое значение.

Стив Уоринг
источник
2
В качестве альтернативы вы всегда можете создать файл bulk preferences.xml, который используете ТОЛЬКО для установки значений по умолчанию. Например, если у вас есть R.xml.prefs_device, R.xml.prefs_testи R.xml.prefs_admin. Вы можете создать один PREFS файл, содержащий все префов из вышеизложенного: R.xml.prefs_for_loading_default_values. Тогда используйте это с PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo
Что касается эффективности: если вы вызовете это в onCreate()подклассе Application(зарегистрированном в манифесте), в любом случае он будет вызываться только один раз при запуске приложения. Для производительности было бы более уместно (если вообще) не выполнять синтаксический анализ каждый раз при запуске приложения (а не только при его первом запуске), и это то, что falseпроисходит. Таким образом, это больше вопрос о том, нужна ли вам проверка при каждом запуске (например, когда могут быть добавлены новые настройки) или достаточно, если это делается при первом запуске (или при сбросе настроек).
user905686
2

Например, расширение DialogPreferenceя делаю так:

@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
    super.onSetInitialValue(restore, defaultValue);

    if (restore) {
        mValue = shouldPersist() ? getPersistedString(mDefault) : mDefault;
    } else {
        mValue = mDefault;
    }
}

mDefault может быть:

  • mContext.getResources (). getString (attrs.getAttributeResourceValue (androidns, "defaultValue", 100));
  • то, что вы проиндексировали в R.
Macarse
источник
Хорошо, я немного запутался в том, чего вы пытаетесь достичь. Я не хочу вызывать DialogPreference, мне нужно значение по умолчанию, когда пользователь не пользуется настройками.
Peterdk
Вместо использования настроек по умолчанию в вашем файле prefs.xml вы можете создавать свои собственные классы. Например, вы можете создать новый DialogPreference, расширяющий DialogPreference, и переопределить onSetInitialValue.
Macarse
0

Также убедитесь, что вы никогда раньше не использовали SharedPreferences. Чтобы убедиться, что они не изменены (что означает, что setDefaultValues ​​(this, xml, false) не действует), удалите приложение и загрузите его снова, чтобы убедиться, что никакие значения не затронуты. Это мне помогло.

wirthra
источник