2012-07-23 13 views
14

実行時に、アプリケーションに埋め込まれている言語を知ることは可能でしょうか?アプリケーションのリソース言語を取得

すなわち、このフォルダの存在:

values-en 
values-de 
values-fr 
... 
+1

ちょうど不思議なことですが、デフォルトでは、アプリケーションに配置してからどのロケールがあるのか​​分かりません。 –

+2

あなたはそうです!私はライブラリを作成しているので(エンドデベロッパーは言語を追加できます)、プログラム的に何人が埋め込まれているかを知る必要があります。 – VinceFR

答えて

10

AssetManager.getLocalesは()実際にこれを行う方法です。ただし、パブリックAPIから作成するすべてのAssetManagerには、検索パスにフレームワークリソースが含まれています。そのため、AssetManager.getLocales()を呼び出すと、フレームワークリソースの一部であるロケールも表示されます。 SDKでこれを回避する方法はありません。申し訳ありません。 I上記の答えに触発さ

1

あなたはこのについて話していますか?あなたは、デバイスからロケールを取得する必要があり、あなたはどの言語がロケールから示さ取得され得ることができるので、

String language = Locale.getDefault().getDisplayLanguage(); 
+0

いいえ、このメソッドはデフォルトの言語を返して、私のresフォルダに指定されたすべての言語を知りたい – VinceFR

2

これらのres-langは実際には、ロケールに依存します。..

Locale myPhoneLocale = Locale.getDefault(); 

それから(getDisplayLanguageを呼び出すことができますどの言語が表示されているかを知ることができます。

参考:Locale

+0

同じuser370305として、私は自分のアプリケーションで利用可能なすべての言語を知りたいです。 – VinceFR

1

AssetManager.getLocales()呼び出してみてください。

は、この資産マネージャがためにデータが含まれているロケールを取得します。

list()を使用してリストを取得できますか。

指定されたパスにあるすべてのアセットの文字列配列を返します。

+0

getLocales()は私のアプリケーションではなく私のデバイスで利用可能な言語を返します。 list(文字列パス)はトリックを行いません – VinceFR

0

あなたが意味するか:

String[] locales = getAssets().getLocales(); 

これは、あなたがお使いのデバイスが持っている言語を取得してみましょうでしょう。

+1

自分のデバイスにある言語ではなく、自分のアプリケーションにある言語を使用したくありません – VinceFR

11

values-deという名前のフォルダがあっても、そこにリソースがあるわけではありません。 string.xmlvalues-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

+0

これは答えにする必要があります – injecteer

2

が用意された翻訳に基づいて、すべてのアプリの言語を取得する簡単な方法を作成しました: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のを使用して、誰のために誰か...

2

に役立つだろう、私は次のようにそれをやりましたディレクトリ名を取得し、そこからロケールを取り出します。それは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 

としてアクセスできるBuildConfigString[]を追加します。

私はGradle/Groovyのエキスパートではありませんので、これは間違いなくちょっとしたことかもしれません。

推理 - パウエルジエバのソリューションを実装するには多すぎる問題にぶつかりました。私は、翻訳がクラウドソースであったため、信頼できる文字列が「比較」できませんでした。最も簡単な方法は、利用可能な値のblahフォルダを実際に見ることでした。 Injecteer @によってコードで触発さ

0

私は次のことを行っている:

アプリがサポートしている言語のリストについては、それを検出することができないので、デフォルトの言語を渡す必要があります

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メンドに触発さ

3

を移入するために使用したい場合は、まず最初にのためにあります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:

  • 小規模APKを - resConfigsは、ライブラリからリソースをカットしますあなたは必要ありません(いくつかは何百もあります)
  • 高速 - リソース設定を解析する必要はありません