web-dev-qa-db-fra.com

comment obtenir une chaîne de différents paramètres régionaux dans Android?

Je souhaite donc obtenir la valeur d'une chaîne dans plusieurs paramètres régionaux, quel que soit le paramètre local actuel de l'appareil/de l'application. Comment dois-je faire ça?

Fondamentalement, j'ai besoin d'une fonction getString(int id, String locale) plutôt que getString(int id)

Comment pourrais-je faire ça?

Merci

58
cheng yang

[~ # ~] note [~ # ~] Si votre API minimale est de 17+, allez directement au bas de cette réponse. Sinon, lisez la suite ...

Si vous avez différents dossiers res pour différents paramètres régionaux, vous pouvez faire quelque chose comme ceci:

Configuration conf = getResources().getConfiguration();
conf.locale = new Locale("pl");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources resources = new Resources(getAssets(), metrics, conf);
String str = resources.getString(id);

Alternativement, vous pouvez simplement redémarrer votre activité en utilisant la méthode indiquée par @jyotiprakash.

[~ # ~] note [~ # ~] L'appel du constructeur Resources comme celui-ci change quelque chose en interne dans Android. Vous devrez invoquer le constructeur avec votre locale d'origine pour récupérer les choses telles qu'elles étaient.

[~ # ~] modifier [~ # ~] Une recette légèrement différente (et quelque peu plus propre) pour récupérer des ressources à partir d'un lieu spécifique est:

Resources res = getResources();
Configuration conf = res.getConfiguration();
Locale savedLocale = conf.locale;
conf.locale = desiredLocale; // whatever you want here
res.updateConfiguration(conf, null); // second arg null means don't change

// retrieve resources from desired locale
String str = res.getString(id);

// restore original locale
conf.locale = savedLocale;
res.updateConfiguration(conf, null);

À partir du niveau 17 de l'API, vous devez utiliser conf.setLocale() au lieu de définir directement conf.locale. Cela mettra correctement à jour la direction de la mise en page de la configuration s'il vous arrive de basculer entre les paramètres régionaux de droite à gauche et de gauche à droite. (La mise en page a été introduite en 17.)

Il ne sert à rien de créer un nouvel objet Configuration (comme @Nulano le suggère dans un commentaire) car appeler updateConfiguration va changer la configuration d'origine obtenue en appelant res.getConfiguration().

J'hésiterais à regrouper cela dans une méthode getString(int id, String locale) si vous allez charger plusieurs ressources de chaîne pour une locale. La modification des paramètres régionaux (à l'aide de l'une ou l'autre recette) nécessite que le framework fasse beaucoup de travail pour relier toutes les ressources. Il est préférable de mettre à jour les paramètres régionaux une fois, de récupérer tout ce dont vous avez besoin, puis de rétablir les paramètres régionaux.

[~ # ~] modifier [~ # ~] (Merci à @Mygod):

Si votre niveau d'API minimum est 17+, il y a une bien meilleure approche, comme indiqué dans cette réponse sur un autre thread. Par exemple, vous pouvez créer plusieurs objets Resource, un pour chaque paramètre régional dont vous avez besoin, avec:

@NonNull Resources getLocalizedResources(Context context, Locale desiredLocale) {
    Configuration conf = context.getResources().getConfiguration();
    conf = new Configuration(conf);
    conf.setLocale(desiredLocale);
    Context localizedContext = context.createConfigurationContext(conf);
    return localizedContext.getResources();
}

Ensuite, récupérez simplement les ressources que vous aimez dans l'objet Resource localisé renvoyé par cette méthode. Il n'est pas nécessaire de réinitialiser quoi que ce soit une fois que vous avez récupéré les ressources.

119
Ted Hopp

Voici une version combinée des approches décrites par Ted Hopp . De cette façon, le code fonctionne pour toutes les versions Android:

public static String getLocaleStringResource(Locale requestedLocale, int resourceId, Context context) {
    String result;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // use latest api
        Configuration config = new Configuration(context.getResources().getConfiguration());
        config.setLocale(requestedLocale);
        result = context.createConfigurationContext(config).getText(resourceId).toString();
    }
    else { // support older Android versions
        Resources resources = context.getResources();
        Configuration conf = resources.getConfiguration();
        Locale savedLocale = conf.locale;
        conf.locale = requestedLocale;
        resources.updateConfiguration(conf, null);

        // retrieve resources from desired locale
        result = resources.getString(resourceId);

        // restore original locale
        conf.locale = savedLocale;
        resources.updateConfiguration(conf, null);
    }

    return result;
}

Exemple d'utilisation:

String englishName = getLocaleStringResource(new Locale("en"), R.string.name, context);

Remarque

Comme déjà indiqué dans la réponse d'origine, il peut être plus efficace de remplacer plusieurs appels du code ci-dessus par une seule modification de configuration et plusieurs appels resources.getString ().

19
Johnson_145