2012-07-23 15 views
14

क्या यह संभव है, रनटाइम पर, यह जानने के लिए कि मेरे ऐप में कौन सी संसाधन भाषाएं एम्बेड की गई हैं?एप्लिकेशन की संसाधन भाषाएं

इस फ़ोल्डर की उपस्थिति यानी:

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

बस उत्सुक: लेकिन डिफ़ॉल्ट रूप से आप नहीं जानते कि आप उन्हें ऐप में रखने के बाद से कौन से लोकेशंस हैं? –

+2

आप सही हैं!लेकिन मैं एक पुस्तकालय बना रहा हूं (इसलिए अंत डेवलपर्स भाषाएं जोड़ सकते हैं) और मुझे प्रोग्रामेटिक रूप से पता होना चाहिए कि कितने एम्बेडेड – VinceFR

उत्तर

10

AssetManager.getLocales() वास्तव में जिस तरह से यह करने के लिए है। हालांकि, सार्वजनिक एपीआई से आपके द्वारा बनाए गए प्रत्येक एसेट मैनेजर में भी फ्रेमवर्क संसाधनों को इसके खोज पथ में शामिल किया गया है ... इसलिए जब आप AssetManager.getLocales() को कॉल करते हैं तो आप फ्रेमवर्क संसाधनों का हिस्सा होने वाले किसी भी स्थानीय क्षेत्र को भी देखेंगे। एसडीके के साथ इसे पाने के लिए कोई रास्ता नहीं है, क्षमा करें।

1

आप इस बारे में बात कर रहे हैं?

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

नहीं हैं, यह विधि सिर्फ डिफ़ॉल्ट भाषा लौटाती है, मैं अपने res फ़ोल्डर – VinceFR

2

इन रेस-लैंग वास्तव में पर स्थलों निर्भर करता है, ताकि आप डिवाइस से स्थान प्राप्त करने की आवश्यकता है और आप जो भाषा के स्थान से पता चला जा रहा है प्राप्त कर सकते हैं ..

Locale myPhoneLocale = Locale.getDefault(); 

इसके बाद आप कॉल कर सकते हैं getDisplayLanguage () यह जानने के लिए कि कौन सी भाषा दिखायी जा रही है।

संदर्भ: Locale

+0

में निर्दिष्ट सभी भाषाओं को जानना चाहता हूं उपयोगकर्ता 370305 के रूप में, मैं अपने ऐप – VinceFR

1

बुला AssetManager.getLocales() प्रयास करें:

स्थानों है कि इस संपत्ति प्रबंधक के लिए डेटा है प्राप्त करें।

या आप list() का उपयोग करके एक सूची प्राप्त कर सकते हैं, तो आप कोशिश कर सकते हैं।

दिए गए पथ पर सभी संपत्तियों की एक स्ट्रिंग सरणी लौटाएं।

+0

getLocales() में सभी उपलब्ध भाषाओं को जानना चाहता हूं, मुझे अपने ऐप पर नहीं, मेरे डिवाइस पर उपलब्ध भाषा लौटाएं। सूची (स्ट्रिंग पथ) चाल – VinceFR

0

तुम्हारा मतलब क्या:

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

यह आपको भाषा है कि आपके डिवाइस मिलता है जाएगा।

+1

नहीं करता है, मैं अपनी डिवाइस के पास ऐसी भाषा नहीं रखना चाहता हूं, लेकिन मेरे आवेदन में – VinceFR

11

यह जटिल है क्योंकि यहां तक ​​कि यदि आपके पास values-de नामक फ़ोल्डर है, तो इसका मतलब यह नहीं है कि आपके पास कोई संसाधन है। यदि आपके पास values-de में है तो इसका मतलब यह नहीं है कि आपके पास स्ट्रिंग मान है।

मान:

<resources> 
    <string name="app_name">LocTest</string> 
    <string name="hello_world">Hello world!</string> 
    <string name="menu_settings">Settings</string> 
</resources> 

मान-de:

<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]); 
    } 
} 

यह एक है गलती - आप एक मूल्य की जांच कर सकते हैं चाहे उसका अनुवाद हो।

LOCALE (5667):: 51: en_NZ LOCALE (5667): 52: uk_UA LOCALE (5667): 53: nl_BE LOCALE (5667): 54

गंदा कोड ऊपर की तरह कुछ प्रिंट होगा : de_DE अलग-अलग LOCALE (5667): 54: हेलो वेल्ट! हैलो दुनिया! de_DE LOCALE (5667): 55: ka_GE LOCALE (5667): 56: sv_SE LOCALE (5667): 57: bg_BG LOCALE (5667): 58: de_CH भिन्न LOCALE (5667): 58: हेलो वेल्ट! नमस्ते दुनिया!de_CH LOCALE (5667): 59: fr_CH LOCALE (5667): 60: fi_FI

+0

यह उत्तर होना चाहिए – injecteer

2

मैं ऊपर जवाब से प्रेरित होकर एक सरल विधि बनाया प्रदान की अनुवाद के आधार पर सभी एप्लिकेशन की भाषाओं पाने के लिए:

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; 
} 

जहां के रूप में id आर्ग एक R.string.some_message जो सभी अनुवाद में प्रदान की है और स्पष्ट रूप से पहचाने होता है इस्तेमाल किया जाना चाहिए पाठ, जैसे "Do you really want to delete the object?"

शायद यह किसी की मदद करेंगे ...

2

Gradle का उपयोग कर किसी के लिए, मैं यह इतना नीचे यह सब strings.xml को पार करता पसंद आया , निर्देशिका से नाम और आंकड़े वहां से स्थानीय लोगों को पकड़ लेता है। यह एक String[] रूप 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 

तो ऊपर काम के बाद (prebuild पर) होता है BuildConfig.TRANSLATION_ARRAY स्थानों की अपनी सूची है आप उपयोग कर सकते हैं जो BuildConfig में जोड़ता है।

मैं ग्रैडल/ग्रोवी विशेषज्ञ नहीं हूं इसलिए यह निश्चित रूप से थोड़ा सा साफ हो सकता है।

तर्क - मैं पावेलज़ीबा के समाधान को लागू करने में बहुत से मुद्दों में भाग गया, मेरे पास 'तुलना' करने के लिए कोई विश्वसनीय तार नहीं था क्योंकि अनुवाद भीड़ के थे। तब सबसे आसान तरीका वास्तव में मूल्य-ब्लाह फ़ोल्डर्स को देखना था।

0

मैंने किया है 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

3

ठीक कर लो से प्रेरित होकर पॉप्युलेट करने के लिए उपयोग करना चाहते हैं के लिए है

defaultConfig { 
     .... 

     def locales = ["en", "it", "pl", "fr", "es", "de", "ru"] 

     buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}" 
     resConfigs locales 
    } 
फिर जावा में

का उपयोग करें:: hak के समाधान मैं कुछ थोड़ा क्लीनर बनाया

BuildConfig.TRANSLATION_ARRAY 

इस विधि का Advatages:

  • छोटे apk - resConfigs बाहर संसाधनों पुस्तकालयों से कट जाएगा जो आपको इसकी आवश्यकता नहीं है (कुछ सैकड़ों हैं)
  • फास्ट - संसाधन कॉन्फ़िगरेशन पार्स करने की कोई आवश्यकता नहीं
संबंधित मुद्दे