Préférences Android: Comment charger les valeurs par défaut lorsque l'utilisateur n'a pas utilisé l'écran des préférences?

119

J'utilise PreferenceActivity pour permettre à l'utilisateur de définir certaines valeurs. Je lui envoie le fichier xml avec les préférences définies.

J'ai mis tout le android:defaultValue=""pour eux.

Lorsque je lance mon application, j'ai besoin des préférences, ou si elles ne sont pas encore définies manuellement, je veux les valeurs par défaut:

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

Cependant, quand android:defaultValue="true"je reçois encore false. Ainsi, il semble que les valeurs par défaut définies dans le XML ne soient utilisées nulle part sauf lors de l'initialisation de l'écran des préférences.

Je ne veux pas coder en dur les valeurs par défaut dans la getBoolean()méthode. Alors, y a-t-il un moyen d'obtenir les valeurs par défaut en ne les définissant qu'à un seul endroit?

Peterdk
la source

Réponses:

169

cette question est similaire à la mienne:

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

Utilisez simplement ce code dans la onCreateméthode:

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

Il chargera vos préférences à partir de XML et le dernier paramètre ( readAgain) garantira que les préférences de l'utilisateur ne seront pas écrasées. Cela signifie que définir l' readAgainargument sur falsesignifie que cela ne définira les valeurs par défaut que si cette méthode n'a jamais été appelée dans le passé, vous n'avez donc pas à vous soucier de remplacer les paramètres de l'utilisateur à chaque fois que votre activité est créée.

Jetez un œil à PreferenceManager.setDefaultValues dans l'API Android pour une enquête plus approfondie.

pixel
la source
Pouvons-nous l'utiliser sur une autre variable SharedPrefrence que nous créons?
Amol Gupta
8
En outre, si votre application a plusieurs points d'entrée, placez - le dans onCreate()de Application.
SD
2
Cela ne fonctionne pas si vous utilisez un booléen et que la valeur par défaut est "false", car l'entrée par défaut ne sera pas créée dans Android 2.x. Un appel à ".getBoolean (KEY, true)" retournera toujours true. Pour Android 4.x, cela fonctionne.
Gunnar Bernstein
10
Le réglage readAgainsur true n'a rien à voir avec l'écrasement des préférences utilisateur. À partir de Javadoc: Remarque: cela ne réinitialisera PAS les préférences à leurs valeurs par défaut.
devconsole
1
Pour ceux qui ont des problèmes avec cette solution (cela ne fonctionne pas ou fonctionne partiellement ou pas toujours) voir la réponse de Steve Waring ci-dessous ( stackoverflow.com/a/25602205/4410376 ). Il est fort probable que vous ayez plusieurs fichiers de préférences partagées, c'est-à-dire qu'Android crée plusieurs fichiers de préférences partagées en fonction de votre configuration ou de votre code désordonné.
Hack06
27

Sachez que si vous utilisez
getSharedPreferences(String sharedPreferencesName, int sharedPreferencesMode)

pour récupérer les préférences, vous devez utiliser pour définir les valeurs par défaut!
PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

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

J'espère que cela peut aider quelqu'un.

Francesco Vadicamo
la source
13

dans la réponse acceptée de Pixel:

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

il est indiqué que cela falsesignifie que les valeurs par défaut ne seront pas écrasées. Ce n'est pas ce qu'il fait, c'est juste un indicateur d'efficacité pour arrêter l'analyse si votre application a plus d'un point d'entrée. Malheureusement, le test n'est pas effectué par fichier de préférences, donc si vous avez plus d'un fichier de préférences, vous devez coder truesur tous sauf le premier.

Si vous êtes préoccupé par l'efficacité, vous pouvez coder quelque chose comme ça.

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 jamais vous ajoutez plus de préférences partagées, définissez simplement SPL sur un nombre élevé.

Steve Waring
la source
2
Comme alternative, vous pouvez toujours créer un fichier preferences.xml en bloc que vous utilisez UNIQUEMENT pour définir les valeurs par défaut. Par exemple, si vous avez R.xml.prefs_device, R.xml.prefs_testet R.xml.prefs_admin. Vous pouvez créer un fichier prefs qui contient tous les prefs de ce qui précède: R.xml.prefs_for_loading_default_values. Ensuite, utilisez-le avec PreferenceManager.setDefaultValues(this, R.xml.prefs_for_loading_default_values, false);
Chantell Osejo
En ce qui concerne l'efficacité: si vous appelez cela dans onCreate()une sous-classe de Application(enregistré dans le manifeste), il ne sera de toute façon appelé qu'une seule fois par démarrage d'application. Pour les performances, il serait plus pertinent (voire pas du tout) de ne pas faire l'analyse à chaque fois que l'application démarre (au lieu de cela uniquement au premier démarrage) et c'est ce que falsefait. Il s'agit donc plus de savoir si vous avez besoin d'une vérification à chaque démarrage (par exemple quand de nouvelles préférences peuvent être ajoutées) ou si c'est suffisant si cela est fait au premier démarrage (ou réinitialiser les préférences).
user905686
2

Par exemple en étendant DialogPreferenceje fais ceci:

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

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

mDefault peut être:

  • mContext.getResources (). getString (attrs.getAttributeResourceValue (androidns, "defaultValue", 100));
  • quelque chose que vous avez répertorié dans R.
Macarse
la source
Ok, je suis un peu perdu ici sur ce que vous essayez d'accomplir. Je ne veux pas appeler DialogPreference, j'ai besoin de la valeur par défaut lorsque l'utilisateur n'utilise pas les préférences.
Peterdk
Au lieu d'utiliser les préférences par défaut dans votre prefs.xml, vous pouvez créer vos propres classes. Par exemple, vous pouvez créer une nouvelle DialogPreference s'étendant de DialogPreference et remplacer onSetInitialValue.
Macarse
0

Assurez-vous également que vous n'avez jamais utilisé les SharedPreferences auparavant. Pour vous assurer qu'ils ne sont pas modifiés (ce qui signifie que setDefaultValues ​​(this, xml, false) n'a aucun effet) désinstallez votre application et téléchargez-la à nouveau pour être sûr qu'aucune valeur n'est touchée. Cela m'a aidé.

Wirthra
la source