実行時に、アプリケーションに埋め込まれている言語を知ることは可能でしょうか?アプリケーションのリソース言語を取得
すなわち、このフォルダの存在:
values-en
values-de
values-fr
...
実行時に、アプリケーションに埋め込まれている言語を知ることは可能でしょうか?アプリケーションのリソース言語を取得
すなわち、このフォルダの存在:
values-en
values-de
values-fr
...
AssetManager.getLocalesは()実際にこれを行う方法です。ただし、パブリックAPIから作成するすべてのAssetManagerには、検索パスにフレームワークリソースが含まれています。そのため、AssetManager.getLocales()を呼び出すと、フレームワークリソースの一部であるロケールも表示されます。 SDKでこれを回避する方法はありません。申し訳ありません。 I上記の答えに触発さ
あなたはこのについて話していますか?あなたは、デバイスからロケールを取得する必要があり、あなたはどの言語がロケールから示さ取得され得ることができるので、
String language = Locale.getDefault().getDisplayLanguage();
いいえ、このメソッドはデフォルトの言語を返して、私のresフォルダに指定されたすべての言語を知りたい – VinceFR
AssetManager.getLocales()
呼び出してみてください。
は、この資産マネージャがためにデータが含まれているロケールを取得します。
list()
を使用してリストを取得できますか。
指定されたパスにあるすべてのアセットの文字列配列を返します。
getLocales()は私のアプリケーションではなく私のデバイスで利用可能な言語を返します。 list(文字列パス)はトリックを行いません – VinceFR
あなたが意味するか:
String[] locales = getAssets().getLocales();
これは、あなたがお使いのデバイスが持っている言語を取得してみましょうでしょう。
自分のデバイスにある言語ではなく、自分のアプリケーションにある言語を使用したくありません – VinceFR
values-de
という名前のフォルダがあっても、そこにリソースがあるわけではありません。 string.xml
がvalues-de
にある場合、そこに文字列値があることを意味するわけではありません。
値:
<resources>
<string name="app_name">LocTest</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
</resources>
値-ド:
<resources>
<string name="hello_world">Hallo Welt!</string>
</resources>
特定のロケールのリソースがデフォルトと異なる場合は、テストすることができます。
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]);
}
}
それは1を持っていますフォルト - あなたはそれが翻訳を持っているかどうか1つの値をチェックできます。
LOCALE(5667):51:en_NZ LOCALE(5667):52:uk_UA LOCALE(5667):53: nl_BE LOCALE(5667):54
上記汚れたコードは次のように印刷され:de_DE別の地域(5667):54:ハロー・ウェルト! こんにちは! de_DE LOCALE(5667):55:ka_GE LOCALE(5667):56:sv_SE ロケール(5667):57:bg_BGロケール(5667):58:de_CH違う ロカール(5667):58:ハロー・ウェルト!こんにちは世界!de_CH LOCALE(5667):59: fr_CH LOCALE(5667):60:fi_FI
これは答えにする必要があります – injecteer
が用意された翻訳に基づいて、すべてのアプリの言語を取得する簡単な方法を作成しました:id
argは、すべての翻訳で提供され、明確に区別が含まれるR.string.some_message
を使用しなければならないよう
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;
}
場所それはすべてstrings.xml
を横断し、以下のよう"Do you really want to delete the object?"
のようなテキスト、多分それはGradleのを使用して、誰のために誰か...
に役立つだろう、私は次のようにそれをやりましたディレクトリ名を取得し、そこからロケールを取り出します。それはBuildConfig.TRANSLATION_ARRAY
は、ロケールのリストを持っている上記の課題は、(事前に作成上)が発生した後、あなたがそう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
としてアクセスできるBuildConfig
にString[]
を追加します。
私はGradle/Groovyのエキスパートではありませんので、これは間違いなくちょっとしたことかもしれません。
推理 - パウエルジエバのソリューションを実装するには多すぎる問題にぶつかりました。私は、翻訳がクラウドソースであったため、信頼できる文字列が「比較」できませんでした。最も簡単な方法は、利用可能な値のblahフォルダを実際に見ることでした。 Injecteer @によってコードで触発さ
私は次のことを行っている:
アプリがサポートしている言語のリストについては、それを検出することができないので、デフォルトの言語を渡す必要があります
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;
}
結果は、アプリケーションでサポートされている言語のリストmap<key,value>
であるあなたがlistPreferenceメンドに触発さ
を移入するために使用したい場合は、まず最初にのためにありますHAKのソリューション私が何かビットクリーナー作成します。Javaの使用に続いて
defaultConfig {
....
def locales = ["en", "it", "pl", "fr", "es", "de", "ru"]
buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}"
resConfigs locales
}
を:この方法の
BuildConfig.TRANSLATION_ARRAY
ADVATAGES:
ちょうど不思議なことですが、デフォルトでは、アプリケーションに配置してからどのロケールがあるのか分かりません。 –
あなたはそうです!私はライブラリを作成しているので(エンドデベロッパーは言語を追加できます)、プログラム的に何人が埋め込まれているかを知る必要があります。 – VinceFR