Preferencias de Android: ¿Cómo cargar los valores predeterminados cuando el usuario no ha usado la pantalla de preferencias?

119

Estoy usando una PreferenceActivity para permitir que el usuario establezca algunos valores. Lo estoy alimentando con el archivo xml con las preferencias definidas.

He configurado todo android:defaultValue=""para ellos.

Cuando inicio mi aplicación, necesito las preferencias, o si aún no están configuradas manualmente, quiero los valores predeterminados:

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

Sin embargo, cuando android:defaultValue="true"todavía tengo false. Por lo tanto, parece que los valores predeterminados establecidos en el XML no se usan en ningún otro lugar que no sea al inicializar la pantalla de preferencias.

No quiero codificar los valores predeterminados en el getBoolean()método. Entonces, ¿hay alguna manera de obtener los valores predeterminados con solo definirlos en 1 lugar?

Peterdk
fuente

Respuestas:

169

esta pregunta es similar a la mía:

inicializar-preferencias-de-xml-en-actividad-principal

Simplemente use este código en el onCreatemétodo:

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

Cargará sus preferencias desde XML y el último parámetro ( readAgain) garantizará que las preferencias del usuario no se sobrescriban. Eso significa que configurar el readAgainargumento en falsesignifica que esto solo establecerá los valores predeterminados si este método nunca se ha llamado en el pasado, por lo que no necesita preocuparse por anular la configuración del usuario cada vez que se crea su Actividad

Eche un vistazo a PreferenceManager.setDefaultValues en la API de Android para una mayor investigación.

pixel
fuente
¿Podemos usar esto sobre cualquier otra variable SharedPrefrence que creamos?
Amol Gupta
8
Además, si su aplicación tiene múltiples puntos de entrada, colocarlo en onCreate()de Application.
SD
2
Esto no funciona si se usa un booleano y el valor predeterminado es "falso", ya que la entrada predeterminada no se creará en Android 2.x. Una llamada a ".getBoolean (KEY, true)" siempre devolverá verdadero. Para Android 4.x funciona.
Gunnar Bernstein
10
Establecer readAgaincomo verdadero no tiene nada que ver con que se sobrescriban las preferencias del usuario. Desde el Javadoc: Nota: esto NO restablecerá las preferencias a sus valores predeterminados.
devconsole
1
Para aquellos que tienen problemas con esta solución (no funciona o funciona parcialmente o no siempre), consulte la respuesta de Steve Waring a continuación ( stackoverflow.com/a/25602205/4410376 ). Lo más probable es que tenga varios archivos de preferencias compartidas, es decir, Android está creando varios archivos de preferencias compartidas en función de su configuración o código desordenado.
Hack06
27

Tenga en cuenta que si está utilizando
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

para recuperar las preferencias que debe utilizar para establecer los valores predeterminados.
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

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

Espero que esto pueda ayudar a alguien.

Francesco Vadicamo
fuente
13

en la respuesta aceptada de Pixel:

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

se indica que los falsemedios que no se sobrescribirán los valores predeterminados. Esto no es lo que hace, es solo un indicador de eficiencia para detener el análisis si su aplicación tiene más de un punto de entrada. Desafortunadamente, la prueba no se realiza por archivo de preferencias, por lo que si tiene más de un archivo de preferencias, debe codificar trueen todos menos en el primero.

Si le preocupa la eficiencia, puede codificar algo como esto.

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

Si alguna vez agrega más preferencias compartidas, simplemente configure SPL en un número alto.

Steve Waring
fuente
2
Como alternativa, siempre puede crear un archivoferences.xml masivo que SOLO usa para establecer valores predeterminados. Por ejemplo, si tiene R.xml.prefs_device, R.xml.prefs_testy R.xml.prefs_admin. Se puede crear un archivo de preferencias que contiene todas las Preferencias de lo anterior: R.xml.prefs_for_loading_default_values. Luego PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo
Con respecto a la eficiencia: si lo llamas en onCreate()una subclase de Application(registrado en el manifiesto), solo se llamará una vez por inicio de la aplicación de todos modos. Para el rendimiento, sería más relevante (en todo caso) no realizar el análisis cada vez que se inicia la aplicación (en lugar de eso, solo en su primer inicio) y esto es lo que falsehace. Por lo tanto, es más una cuestión de si necesita una verificación en cada inicio (por ejemplo, cuándo se pueden agregar nuevas preferencias) o si es suficiente si se hace en el primer inicio (o se restablecen las preferencias).
user905686
2

Por ejemplo, extendiendo DialogPreferencehago esto:

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

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

mDefault puede ser:

  • mContext.getResources (). getString (attrs.getAttributeResourceValue (androidns, "defaultValue", 100));
  • algo que haya indexado en R.
Macarse
fuente
Ok, estoy un poco perdido aquí acerca de lo que estás tratando de lograr. No quiero llamar a DialogPreference, necesito el valor predeterminado cuando el usuario no usa las Preferencias.
Peterdk
En lugar de usar Preferencias predeterminadas en su prefs.xml, puede crear sus propias clases. Por ejemplo, puede crear una nueva DialogPreference que se extienda desde DialogPreference y anular onSetInitialValue.
Macarse
0

También asegúrese de que nunca antes ha utilizado SharedPreferences. Para asegurarse de que no se modifiquen (lo que significa que setDefaultValues ​​(this, xml, false) no tiene ningún efecto) desinstale su aplicación y cárguela nuevamente para asegurarse de que no se toque ningún valor. Eso me ayudó.

wirthra
fuente