48 votes

Fichier de configuration Android

Quel est le meilleur moyen et comment puis-je configurer un fichier de configuration pour une application ?

Je veux que l'application soit capable de consulter un fichier texte sur la carte SD et d'en extraire certaines informations dont elle a besoin.

3 votes

À quoi sert ce fichier de configuration ? Avez-vous besoin de sauvegarder les paramètres de l'utilisateur ou autre ? Il y a beaucoup de bons guides sur l'utilisation de SharedPreferences et autres.

0 votes

Il s'agit pour l'instant de charger un nom pour le pda dans l'application, et je veux pouvoir changer ce nom à l'avenir sans avoir à modifier le code dans l'application.

0 votes

Assurez-vous de vérifier la question liée. La réponse à la question sur les propriétés correspond à ce que je voulais obtenir de cette question. Elle ressemble également à ce que @Beginner recherchait.

116voto

grim Points 1039

Si votre application est destinée à être rendue publique et si vous avez des données sensibles dans votre configuration, comme des clés d'API ou des mots de passe, je vous suggère d'utiliser préférences sécurisées au lieu de Préférences partagées car, en fin de compte, les préférences partagées sont stockées dans un XML en texte clair, et sur un téléphone enraciné, il est très facile pour une application d'accéder aux préférences partagées d'un autre.

Par défaut, il ne s'agit pas d'une sécurité à toute épreuve (en fait, il s'agit plutôt d'une sécurité à toute épreuve). l'obscurcissement des préférences), mais il s'agit d'une solution rapide pour rendre pour rendre votre application Android plus sûre. Par exemple, elle empêchera les utilisateurs de sur les appareils enracinés de modifier facilement les préférences partagées de votre application. ( lien )

Je suggère quelques autres méthodes :

* Méthode 1 : utiliser un .properties avec Propriétés__

Pour :

  1. Facile à modifier à partir de l'IDE que vous utilisez
  2. Plus sécurisé : puisqu'il est compilé avec votre application
  3. Il est facile d'y déroger si vous utilisez Construire des variantes/Flavors
  4. Vous pouvez également écrire dans la configuration

Cons :

  1. Vous avez besoin d'un contexte
  2. Vous pouvez également écrire dans la configuration (oui, cela peut aussi être un con)
  3. (autre chose ?)

Tout d'abord, créez un fichier de configuration : res/raw/config.properties et ajouter quelques valeurs :

api_url=http://url.to.api/v1/
api_key=123456

Vous pouvez ensuite accéder facilement aux valeurs avec quelque chose comme ceci :

package some.package.name.app;

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public final class Helper {
    private static final String TAG = "Helper";

    public static String getConfigValue(Context context, String name) {
        Resources resources = context.getResources();

        try {
            InputStream rawResource = resources.openRawResource(R.raw.config);
            Properties properties = new Properties();
            properties.load(rawResource);
            return properties.getProperty(name);
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, "Unable to find the config file: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "Failed to open config file.");
        }

        return null;
    }
}

Utilisation :

String apiUrl = Helper.getConfigValue(this, "api_url");
String apiKey = Helper.getConfigValue(this, "api_key");

Bien sûr, cela pourrait être optimisé pour lire le fichier de configuration une fois et obtenir toutes les valeurs.

Méthode 2 : Utiliser AndroidManifest.xml méta-données élément :

Personnellement, je n'ai jamais utilisé cette méthode car elle ne me semble pas très flexible.

Dans votre AndroidManifest.xml ajoutez quelque chose comme :

...
<application ...>
    ...

    <meta-data android:name="api_url" android:value="http://url.to.api/v1/"/>
    <meta-data android:name="api_key" android:value="123456"/>
</application>

Maintenant une fonction pour récupérer les valeurs :

public static String getMetaData(Context context, String name) {
    try {
        ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
        Bundle bundle = ai.metaData;
        return bundle.getString(name);
    } catch (PackageManager.NameNotFoundException e) {
        Log.e(TAG, "Unable to load meta-data: " + e.getMessage());
    }
    return null;
}

Utilisation :

String apiUrl = Helper.getMetaData(this, "api_url");
String apiKey = Helper.getMetaData(this, "api_key");

Méthode 3 : Utiliser buildConfigField dans votre Saveur :

Je n'ai pas trouvé cela dans la documentation/formation officielle d'Android, mais cet article de blog est très utile.

Fondamentalement, la mise en place d'une saveur de projet (par exemple prod ), puis dans le dossier de votre application build.gradle avoir quelque chose comme :

productFlavors {
    prod {
        buildConfigField 'String', 'API_URL', '"http://url.to.api/v1/"'
        buildConfigField 'String', 'API_KEY', '"123456"'
    }
}

Utilisation :

String apiUrl = BuildConfig.API_URL;
String apiKey = BuildConfig.API_KEY;

0 votes

Excellente réponse avec tous les détails nécessaires. La saveur sera l'option la plus appropriée dans la plupart des cas. Merci d'avoir pris le temps de publier cette réponse

0 votes

Je regarde donc les solutions 1 et 3, mais mon cas d'utilisation (qui, j'en suis sûr, est courant) est d'avoir une adresse d'hôte API dynamique mais avec des chemins de ressources partagés par toutes les variantes de construction. En gros, ce que je cherche, c'est un fichier texte pour stocker les paires clé/valeur (dans n'importe quel format) dans l'espace par défaut/global (c'est-à-dire principal) et ensuite dans un espace spécifique à la variante de construction, puis d'écraser ces objets ensemble avec la variante de construction ayant la priorité. cela existe-t-il ? SharedPreferences Le système d'information de l'entreprise a été mis en place par le ministère de l'économie, des finances et de l'industrie...

0 votes

Mais cela ne convient pas non plus car je ne vois pas l'intérêt d'avoir des valeurs de configuration spécifiques qui prévalent sur les valeurs communes.

10voto

Reno Points 22138

Vous pouvez y parvenir en utilisant préférences partagées

Il existe un guide très détaillé sur la façon d'utiliser les préférences partagées sur la page Google Android https://developer.Android.com/guide/topics/data/data-storage.html#pref

3 votes

C'est vrai que j'ai pensé aux préférences partagées comme les variables globales et non le fichier de configuration, vous pouvez voir que je viens d'un milieu de développement web et non mobile :)

2 votes

Un exemple de fichier texte de préférences partagé, et une activité y accédant ?

6 votes

Comment les préférences partagées peuvent-elles être utilisées comme sources de configuration ? Je vois la configuration comme un fichier "codé en dur" (json, xml etc) avec des données définies par le développeur à utiliser dans l'application. Les préférences partagées peuvent contenir des données que vous générez dans votre application, mais comment peuvent-elles contenir des données prédéfinies ?

8voto

Mudassir Points 8017

Si vous souhaitez stocker les préférences de votre application, Android fournit Préférences partagées pour ça.
Voici le lien vers la ressource officielle de formation.

0 votes

Un exemple de fichier texte de préférences partagé, et une activité y accédant ?

0 votes

@Uzi : Pour lire les SharedPreferences, vous pouvez utiliser la méthode suivante ; boolean showInfo = preferences.getBoolean( Constants.PREFERENCES_INFO_SHOWN, false);

0 votes

Comment puis-je accéder à un fichier de préférences que j'ai stocké sur la carte sd et à quoi dois-je ressembler merci ?

2voto

Hardian Points 1122

J'ai répondu à cette exigence récemment, en notant ici comment j'ai fait.

l'application doit pouvoir consulter un fichier texte sur la carte sd et récupérer certaines informations dont elle a besoin

Exigence :

  1. La valeur de configuration (score_threshold) doit être disponible sur la carte SD. Ainsi, quelqu'un peut changer les valeurs après avoir publié l'apk.
  2. Le fichier de configuration doit être disponible dans le répertoire "/sdcard/config.txt" du matériel Android.

Le contenu du fichier config.txt est le suivant,

score_threshold=60

Créez une classe utilitaire Config.java, pour lire et écrire un fichier texte.

import android.util.Log;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

public final class Config {

    private static final String TAG = Config.class.getSimpleName();
    private static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/config.txt";
    private static Config sInstance = null;

    /**
     * Gets instance.
     *
     * @return the instance
     */
    public static Config getInstance() {
        if (sInstance == null) {
            synchronized (Config.class) {
                if (sInstance == null) {
                    sInstance = new Config();
                }
            }
        }
        return sInstance;
    }

    /**
     * Write configurations values boolean.
     *
     * @return the boolean
     */
    public boolean writeConfigurationsValues() {

        try (OutputStream output = new FileOutputStream(FILE_PATH)) {

            Properties prop = new Properties();

            // set the properties value
            prop.setProperty("score_threshold", "60");

            // save properties
            prop.store(output, null);

            Log.i(TAG, "Configuration stored  properties: " + prop);
            return true;
        } catch (IOException io) {
            io.printStackTrace();
            return false;
        }
    }

    /**
     * Get configuration value string.
     *
     * @param key the key
     * @return the string
     */
    public String getConfigurationValue(String key){
        String value = "";
        try (InputStream input = new FileInputStream(FILE_PATH)) {

            Properties prop = new Properties();

            // load a properties file
            prop.load(input);
            value = prop.getProperty(key);
            Log.i(TAG, "Configuration stored  properties value: " + value);
         } catch (IOException ex) {
            ex.printStackTrace();
        }
        return value;
    }
}

Créez une autre classe utilitaire pour écrire le fichier de configuration lors de la première exécution de l'application, Note : La permission de lecture/écriture de la carte SD doit être définie pour l'application.

public class ApplicationUtils {

  /**
  * Sets the boolean preference value
  *
  * @param context the current context
  * @param key     the preference key
  * @param value   the value to be set
  */
 public static void setBooleanPreferenceValue(Context context, String key, boolean value) {
     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
     sp.edit().putBoolean(key, value).commit();
 }

 /**
  * Get the boolean preference value from the SharedPreference
  *
  * @param context the current context
  * @param key     the preference key
  * @return the the preference value
  */
 public static boolean getBooleanPreferenceValue(Context context, String key) {
     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
     return sp.getBoolean(key, false);
 }

}

Dans votre activité principale, onCreate()

if(!ApplicationUtils.getBooleanPreferenceValue(this,"isFirstTimeExecution")){
           Log.d(TAG, "First time Execution");
           ApplicationUtils.setBooleanPreferenceValue(this,"isFirstTimeExecution",true);
           Config.getInstance().writeConfigurationsValues();
}
// get the configuration value from the sdcard.
String thresholdScore = Config.getInstance().getConfigurationValue("score_threshold");
Log.d(TAG, "thresholdScore from config file is : "+thresholdScore );

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X