È possibile, in fase di runtime, sapere quali risorse sono incorporate nella mia app?ottenere le lingue delle risorse dell'applicazione
cioè la presenza di questo cartelle:
values-en
values-de
values-fr
...
È possibile, in fase di runtime, sapere quali risorse sono incorporate nella mia app?ottenere le lingue delle risorse dell'applicazione
cioè la presenza di questo cartelle:
values-en
values-de
values-fr
...
AssetManager.getLocales() è in realtà il modo per farlo. Tuttavia, dall'API pubblica ogni AssetManager che crei ha anche le risorse del framework incluse nel suo percorso di ricerca ... quindi quando chiami AssetManager.getLocales() vedrai anche le impostazioni locali che fanno parte delle risorse del framework. Non c'è modo di aggirare questo con l'SDK, mi dispiace.
Stai parlando di questo?
String language = Locale.getDefault().getDisplayLanguage();
no, questo metodo restituisce solo la lingua predefinita, voglio conoscere tutte le lingue specificate nella mia cartella di ricerca – VinceFR
questi res-lang in realtà dipende da locali, quindi è necessario ottenere locale dal dispositivo e si può ottenere che il linguaggio è sempre mostrata dalla locale ..
Locale myPhoneLocale = Locale.getDefault();
È quindi possibile chiamare getDisplayLanguage () per sapere quale lingua viene mostrata.
Riferimento: Locale
stessa come utente370305, voglio conoscere tutte le lingue disponibili nella mia app – VinceFR
provare a chiamare AssetManager.getLocales()
:
Ricevere le impostazioni internazionali che questo asset manager contiene i dati per.
Oppure si può provare se è possibile ottenere un elenco utilizzando list()
.
Restituisce un array di stringhe di tutte le risorse nel percorso specificato.
getLocales() restituiscimi la lingua disponibile sul mio dispositivo, non sulla mia app. L'elenco (percorso stringa) non fa il trucco – VinceFR
vuoi dire:
String[] locales = getAssets().getLocales();
Questo potrebbe farvi ottenere la lingua che il dispositivo ha.
Non voglio avere le lingue del mio dispositivo ma la lingua che la mia applicazione ha – VinceFR
È complicato perché anche se si dispone di una cartella denominata values-de
, ciò non significa che ci siano risorse lì. Se hai string.xml
in values-de
, non significa che tu abbia il valore di stringa lì.
valori:
<resources>
<string name="app_name">LocTest</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
</resources>
valori-de:
<resources>
<string name="hello_world">Hallo Welt!</string>
</resources>
È possibile verificare se una risorsa per un locale specifico è diverso da quello predefinito:
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]);
}
}
ha uno errore: puoi controllare un valore indipendentemente dalla traduzione.
Il codice sporco sopra stamperà qualcosa del tipo:
LOCALE (5667): 51: en_NZ LOCALE (5667): 52: uk_UA LOCALE (5667): 53: nl_BE LOCALE (5667): 54 : de_DE DIFFERENT LOCALE (5667): 54: Hallo Welt! Ciao mondo! de_DE LOCALE (5667): 55: ka_GE LOCALE (5667): 56: sv_SE LOCALE (5667): 57: bg_BG LOCALE (5667): 58: de_CH DIFFERENTE LOCALE (5667): 58: Hallo Welt! Ciao mondo!de_CH LOCALE (5667): 59: fr_CH LOCALE (5667): 60: fi_FI
questa dovrebbe essere una risposta – injecteer
Ispirato alle risposte di cui sopra ho creato un metodo semplice per ottenere tutte le lingue di app in base a traduzioni fornite:
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;
}
dove come id
arg deve essere utilizzato un R.string.some_message
che è fornito in tutte le traduzioni e contiene chiaramente distinguibili il testo, come "Do you really want to delete the object?"
Forse sarebbe d'aiuto a qualcuno ...
per chiunque utilizzi Gradle, l'ho fatto in questo modo sotto di esso attraversa tutto strings.xml
, prende i nomi delle directory e scopre le impostazioni locali da lì. Si aggiunge un String[]
a BuildConfig
cui è possibile accedere come 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
Così, dopo che si verifica l'operazione di cui sopra (sulla prebuild) il BuildConfig.TRANSLATION_ARRAY
ha l'elenco delle zone.
Non sono un esperto di Gradle/Groovy quindi questo potrebbe sicuramente essere un po 'più ordinato.
Ragionamento: mi sono imbattuto in troppi problemi nell'implementazione della soluzione di pawelzieba, non ho avuto stringhe affidabili da "confrontare" in quanto le traduzioni erano in crowdsourcing. Il modo più semplice allora era di guardare effettivamente le cartelle dei valori-blah disponibili.
Ispirato con il codice @ Injecteer Ho fatto quanto segue:
per l'elenco delle lingue che i supporti app, è necessario passare la lingua predefinita, in quanto non è possibile rilevare
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;
}
il risultato è un elenco map<key,value>
delle lingue supportate dall'applicazione, la prima cosa è se si desidera utilizzare per popolare un listPreference
Ispirato Mend La soluzione di hak ho creato qualcosa di un po 'più pulito:
defaultConfig {
....
def locales = ["en", "it", "pl", "fr", "es", "de", "ru"]
buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}"
resConfigs locales
}
Poi in Java utilizzare:
BuildConfig.TRANSLATION_ARRAY
Advatages di questo metodo:
Solo curioso: ma di default non sapresti quali locali ci sono da quando li hai inseriti nell'app? –
Hai ragione!ma sto creando una libreria (quindi gli sviluppatori finali possono aggiungere lingue) e ho bisogno di sapere a livello di programmazione quanti sono incorporati – VinceFR