Ist es möglich, zur Laufzeit, zu wissen, welche Ressourcen Sprachen sind eingebettet in meine app?erhalten die Ressourcen der Anwendungssprachen
heißt das Vorhandensein dieser Ordner:
values-en
values-de
values-fr
...
Ist es möglich, zur Laufzeit, zu wissen, welche Ressourcen Sprachen sind eingebettet in meine app?erhalten die Ressourcen der Anwendungssprachen
heißt das Vorhandensein dieser Ordner:
values-en
values-de
values-fr
...
AssetManager.getLocales() ist tatsächlich die Art und Weise, dies zu tun. Von der öffentlichen API hat jeder erstellte AssetManager jedoch auch die Framework-Ressourcen in seinem Suchpfad ... Wenn Sie also AssetManager.getLocales() aufrufen, sehen Sie auch alle Gebietsschemata, die Teil der Framework-Ressourcen sind. Es gibt keine Möglichkeit, dies mit dem SDK zu umgehen, sorry.
Sie sprechen darüber sind?
String language = Locale.getDefault().getDisplayLanguage();
Nein, diese Methode nur die Standardsprache zurückgeben, möchte ich alle Sprachen in meinem Ordner res – VinceFR
diese res-lang hängt wirklich von Locales, so müssen Sie locale von Gerät zu erhalten und Sie bekommen können, welche Sprache von locale gezeigt wird immer ..
Locale myPhoneLocale = Locale.getDefault();
Sie können dann getDisplayLanguage nennen () um zu wissen, welche Sprache angezeigt wird.
Referenz: Locale
angegeben kennen Als user370305 möchte ich alle verfügbaren Sprachen in meiner App kennen. – VinceFR
Try Aufruf AssetManager.getLocales()
:
die Locales bekommen, dass diese Asset-Manager für Daten enthält.
Oder Sie können versuchen, wenn Sie eine Liste mit list()
erhalten können.
Gibt ein String-Array aller Assets im angegebenen Pfad zurück.
getLocales() gib mir die Sprache zurück, die auf meinem Gerät verfügbar ist, nicht auf meiner App. Liste (String-Pfad) macht nicht den Trick – VinceFR
Meinen Sie:
String[] locales = getAssets().getLocales();
Dies würde Sie die Sprache, die Ihr Gerät erhalten lassen.
Ich möchte nicht die Sprachen, die mein Gerät haben, aber die Sprache, die meine Anwendung haben – VinceFR
Es ist kompliziert, denn selbst wenn Sie einen Ordner values-de
es bedeutet nicht, Sie haben alle Ressourcen dort genannt haben. Wenn Sie string.xml
in values-de
haben, bedeutet es nicht, dass Sie String-Wert dort haben.
Werte:
<resources>
<string name="app_name">LocTest</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
</resources>
Werte-de:
<resources>
<string name="hello_world">Hallo Welt!</string>
</resources>
können Sie testen, ob eine Ressource für ein bestimmtes Gebietsschema als der Standard unterscheidet:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources r = getResources();
Configuration c = r.getConfiguration();
String[] loc = r.getAssets().getLocales();
for (int i = 0; i < loc.length; i++) {
Log.d("LOCALE", i + ": " + loc[i]);
c.locale = new Locale(loc[i]);
Resources res = new Resources(getAssets(), metrics, c);
String s1 = res.getString(R.string.hello_world);
c.locale = new Locale("");
Resources res2 = new Resources(getAssets(), metrics, c);
String s2 = res2.getString(R.string.hello_world);
if(!s1.equals(s2)){
Log.d("DIFFERENT LOCALE", i + ": "+ s1+" "+s2 +" "+ loc[i]);
}
}
Es hat eine Fehler - Sie können einen Wert prüfen, ob er übersetzt wurde.
Der schmutzige Code wird über Druck etwas wie:
LOCALE (5667): 51: en_NZ LOCALE (5667): 52: uk_UA LOCALE (5667): 53: nl_BE LOCALE (5667): 54 : de_DE VERSCHIEDENE LOCALE (5667): 54: Hallo Welt! Hallo Welt! de_DE LOCALE (5667): 55: ka_GE LOCALE (5667): 56: sv_SE LOCALE (5667): 57: bg_BG LOCALE (5667): 58: de_CH VERSCHIEDENE LOCALE (5667): 58: Hallo Welt! Hallo Welt!de_CH locale (5667): 59: fr_CH locale (5667): 60: fi_FI
Dies sollte eine Antwort sein – injecteer
Inspiriert von den Antworten oben habe ich eine einfache Methode, um alle Sprachen der App zu erhalten, basierend auf bereitgestellten Übersetzungen:
public static Set<String> getAppLanguages(Context ctx, int id) {
DisplayMetrics dm = ctx.getResources().getDisplayMetrics();
Configuration conf = ctx.getResources().getConfiguration();
Locale originalLocale = conf.locale;
conf.locale = Locale.ENGLISH;
final String reference = new Resources(ctx.getAssets(), dm, conf).getString(id);
Set<String> result = new HashSet<>();
result.add(Locale.ENGLISH.getLanguage());
for(String loc : ctx.getAssets().getLocales()){
if(loc.isEmpty()) continue;
Locale l = Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH ? new Locale(loc.substring(0, 2)) : Locale.forLanguageTag(loc);
conf.locale = l;
if(!reference.equals(new Resources(ctx.getAssets(), dm, conf).getString(id))) result.add(l.getLanguage());
}
conf.locale = originalLocale;
return result;
}
wo als id
arg sollte eine R.string.some_message
verwendet werden, die in allen Übersetzungen zur Verfügung gestellt und enthält deutlich unterscheidbar Text, wie "Do you really want to delete the object?"
Vielleicht wäre es jemand helfen ...
Für alle Gradle mit, ich habe es wie so darunter alle strings.xml
durchquert , greift nach den Verzeichnisnamen und ermittelt die Gebietsschemata von dort. Es fügt eine String[]
zu BuildConfig
, die Sie als BuildConfig.TRANSLATION_ARRAY
task buildTranslationArray << {
def foundLocales = new StringBuilder()
foundLocales.append("new String[]{")
fileTree("src/main/res").visit { FileVisitDetails details ->
if(details.file.path.endsWith("strings.xml")){
def languageCode = details.file.parent.tokenize('/').last().replaceAll('values-','').replaceAll('-r','-')
languageCode = (languageCode == "values") ? "en" : languageCode;
foundLocales.append("\"").append(languageCode).append("\"").append(",")
}
}
foundLocales.append("}")
//Don't forget to remove the trailing comma
def foundLocalesString = foundLocales.toString().replaceAll(',}','}')
android.defaultConfig.buildConfigField "String[]", "TRANSLATION_ARRAY", foundLocalesString
}
preBuild.dependsOn buildTranslationArray
So zugreifen können, nachdem die obige Aufgabe (auf vorkompilierte) tritt die BuildConfig.TRANSLATION_ARRAY
Liste der Schauplätze hat.
Ich bin kein Gradle/Groovy Experte, also könnte dies definitiv ein bisschen besser sein.
Schlussfolgerung - Ich stieß auf zu viele Probleme bei der Implementierung von Pawelziebas Lösung. Ich hatte keine zuverlässigen Strings zum "Vergleichen", da die Übersetzungen Crowdsourcing waren. Am einfachsten war es dann, sich die value-blah-Ordner anzusehen.
mit dem Code Inspiriert von @ Injecteer Ich habe das getan folgenden:
für die Liste der Sprachen, die die App unterstützen, ist es notwendig, die Standardsprache zu übergeben, da es nicht möglich ist, zu erkennen,
public static Map<String,String> getAppLanguages(Context context, String appDefaultLang) {
Map<String, String> listAppLocales = new LinkedHashMap<>();
listAppLocales.put("default","Auto");
DisplayMetrics metrics = new DisplayMetrics();
Resources res = context.getResources();
Configuration conf = res.getConfiguration();
String[] listLocates = res.getAssets().getLocales();
for (String locate : listLocates) {
conf.locale = new Locale(locate);
Resources res1 = new Resources(context.getAssets(), metrics, conf);
String s1 = res1.getString(R.string.title_itinerary);
String value = ucfirst(conf.locale.getDisplayName());
conf.locale = new Locale("");
Resources res2 = new Resources(context.getAssets(), metrics, conf);
String s2 = res2.getString(R.string.title_itinerary);
if (!s1.equals(s2)) {
listAppLocales.put(locate, value);
} else if (locate.equals(appDefaultLang)) {
listAppLocales.put(locate, value);
}
}
return listAppLocales;
}
das Ergebnis ist eine Liste map<key,value>
von Sprachen, die von der Anwendung unterstützt, das erste, was ist denn, wenn Sie wollen eine listPreference
Inspiriert von Mend zu füllen verwenden hak Lösung habe ich etwas ein wenig sauberer:
defaultConfig {
....
def locales = ["en", "it", "pl", "fr", "es", "de", "ru"]
buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}"
resConfigs locales
}
dann in Java verwenden:
BuildConfig.TRANSLATION_ARRAY
Advatages dieser Methode:
Nur neugierig: aber wissen Sie standardmäßig nicht, welche Gebietsschemas es gibt, seit Sie sie in die App gelegt haben? –
Sie haben Recht!aber ich erstelle eine Bibliothek (so Ende Entwickler können Sprachen hinzufügen) und ich muss programmgesteuert wissen, wie viele sind eingebettet – VinceFR