Preferências do Android: Como carregar os valores padrão quando o usuário não usou a tela de preferências?

119

Estou usando uma PreferenceActivity para permitir que o usuário defina alguns valores. Estou alimentando o arquivo xml com as preferências definidas.

Eu configurei tudo android:defaultValue=""para eles.

Quando eu inicio meu aplicativo, preciso das preferências ou, se ainda não foram definidas manualmente, quero os valores padrão:

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

No entanto, quando android:defaultValue="true"eu ainda consigo false. Portanto, parece que os valores padrão definidos no XML não são usados ​​em nenhum lugar, exceto ao inicializar a tela de preferências.

Não quero codificar os valores padrão no getBoolean()método. Então, há uma maneira de obter os valores padrão definindo-os em apenas um lugar?

Peterdk
fonte

Respostas:

169

esta questão é semelhante à minha:

initialize-preferences-from-xml-in-main-activity

Basta usar este código no onCreatemétodo:

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

Ele carregará suas preferências do XML e o último parâmetro ( readAgain) garantirá que as preferências do usuário não serão sobrescritas. Isso significa que definir o readAgainargumento como falsesignifica que só irá definir os valores padrão se este método nunca tiver sido chamado no passado, então você não precisa se preocupar em substituir as configurações do usuário cada vez que sua Atividade é criada

Dê uma olhada em PreferenceManager.setDefaultValues na API Android para uma investigação mais aprofundada.

pixel
fonte
Podemos usar isso em qualquer outra varível SharedPrefrence que criamos?
Amol Gupta de
8
Além disso, se o seu aplicativo tem múltiplos pontos de entrada, coloque-o onCreate()de Application.
SD
2
Isso não funciona se estiver usando um booleano e padronizando como "falso", pois a entrada padrão não será criada no Android 2.x. Uma chamada para ".getBoolean (KEY, true)" sempre retornará true. Para Android 4.x, ele funciona.
Gunnar Bernstein
10
Definir readAgaincomo verdadeiro não tem nada a ver com as preferências do usuário sendo substituídas. Do Javadoc: Observação: isso NÃO redefinirá as preferências de volta aos valores padrão.
devconsole
1
Para aqueles que têm problemas com esta solução (ela não funciona ou funciona parcialmente ou nem sempre), veja a resposta de Steve Waring abaixo ( stackoverflow.com/a/25602205/4410376 ). Muito provavelmente você tem vários arquivos de preferências compartilhadas, ou seja, o android está criando vários arquivos de preferências compartilhadas com base em sua configuração ou código confuso.
Hack06,
27

Esteja ciente de que se você estiver usando
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

para recuperar as preferências, você deve usar para definir padrões!
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

Por exemplo:
PreferenceManager.setDefaultValues(this, PREFS_NAME, Context.MODE_PRIVATE, R.xml.preference, false);

Espero que isso possa ajudar alguém.

Francesco Vadicamo
fonte
13

na resposta aceita do Pixel:

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

afirma-se que isso falsesignifica que os padrões não serão substituídos. Não é isso que ele faz, é apenas um sinalizador de eficiência para interromper a análise se seu aplicativo tiver mais de um ponto de entrada. Infelizmente, o teste não é feito por arquivo de preferência, portanto, se você tiver mais de um arquivo de preferência, deverá codificar trueem todos, exceto no primeiro.

Se você está preocupado com a eficiência, pode codificar algo assim.

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();
}

Se você adicionar mais preferências compartilhadas, basta definir o SPL para um número alto.

Steve Waring
fonte
2
Como alternativa, você sempre pode criar um bulk preferences.xml que você usa SOMENTE para definir valores padrão. Por exemplo, se você tem R.xml.prefs_device, R.xml.prefs_teste R.xml.prefs_admin. Você pode criar um arquivo prefs que contém todas as preferências do acima: R.xml.prefs_for_loading_default_values. Em seguida, use isso com PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo
Em relação à eficiência: se você chamar isso onCreate()de uma subclasse de Application(registrado no manifesto), ele só será chamado uma vez por inicialização do aplicativo de qualquer maneira. Para o desempenho, seria mais relevante (se for o caso) não fazer a análise cada vez que o aplicativo é iniciado (em vez disso, apenas na primeira inicialização) e é isso que falseacontece. Portanto, é mais uma questão de saber se você precisa de uma verificação em cada inicialização (por exemplo, quando novas preferências podem ser adicionadas) ou se é o suficiente se feito na primeira inicialização (ou redefinição de preferências).
user905686
2

Por exemplo, estendendo DialogPreferenceI do this:

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

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

mDefault pode ser:

  • mContext.getResources (). getString (attrs.getAttributeResourceValue (androidns, "defaultValue", 100));
  • algo que você indexou em R.
Macarse
fonte
Ok, estou um pouco perdido aqui sobre o que você está tentando alcançar. Não quero chamar DialogPreference, preciso do valor padrão quando o usuário não usa as Preferências.
Peterdk,
Em vez de usar Preferências padrão em seu prefs.xml, você pode criar suas próprias classes. Por exemplo, você pode criar um novo DialogPreference estendendo-se de DialogPreference e substituir o onSetInitialValue.
Macarse,
0

Além disso, certifique-se de nunca ter usado SharedPreferences antes. Para garantir que eles não sejam alterados (o que significa setDefaultValues ​​(this, xml, false) não tem efeito), desinstale seu aplicativo e carregue-o novamente para garantir que nenhum valor seja alterado. Isso me ajudou.

wirthra
fonte