Get country and Language from locale code - android

I have an android method that outputs all the language codes for the speech recognition that are available in the device. The problem is it returns the codes like "en-US", "es-ES", "es-MX"... I would like to know if there is a way to transform these codes into the language's display name (English (USA), Spanish (Spain)...). Thank you for your help.
#Override
public void onReceive(Context context, Intent intent)
{
Bundle results = getResultExtras(true);
if (results.containsKey(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE))
{
languagePreference =
results.getString(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE);
}
if (results.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES))
{
supportedLanguages =
results.getStringArrayList(
RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
}
for(int i=0;i<supportedLanguages.size();i++){
System.out.println("The language supported is: "+supportedLanguages.get(i));
}
}

Yes you can use Locale.forLanguageTag:
Locale locale = Locale.forLanguageTag("en-US");
System.out.println(locale.getDisplayName());
// "English (United States)"

Build a dictionary from a data source of ISO Language codes:
https://www.andiamo.co.uk/resources/iso-language-codes

Related

Android. Espresso. How to check that text is shown in a specific language without hard code strings?

I need to check my fragment when I change the app language.
Here is my Android Espresso test:
#Test
public void changeLanguages() {
Resources resources = context.getResources();
String[] appLanguages = resources.getStringArray(R.array.app_lang_codes);
for (int index = 0; index < appLanguages.length; index++) {
String currentLang = appLanguages[index];
Locale currentLocale = new Locale(currentLang);
if (currentLocale.equals(AppLanguageService.getLocaleRO(context))) {
// click Romanian
onView(withId(R.id.containerLanguageRO)).perform(click());
onView(withId(R.id.textViewSelectLanguage)).check(matches(withText("Selecți limba")));
} else if (currentLocale.equals(AppLanguageService.getLocaleEN(context))) {
// click English
onView(withId(R.id.containerLanguageEN)).perform(click());
onView(withId(R.id.textViewSelectLanguage)).check(matches(withText("Select language")));
}
}
}
Ant it's working fine. OK!
But as you can see I need to hard code the string for a specific language for the test.
"Selecți limba" and "Select language". And I think it's not good.
Is it possible to not use hard code strings to check that text is shown in a specific language?
You can use
mActivityRule.getActivity()
to get the activity you are testing. With this you could fetch a string from your resources like this:
mActivityRule.getActivity().getResources().getString(R.string.your_string)
You could rewrite your check like this:
onView(withId(R.id.textViewSelectLanguage)).check(matches(withText(mActivityRule.getActivity().getResources().getString(R.string.your_string))));
where your_string is the name of your string resource in your strings.xml files.

Prevent change numbers localization when change android language localization

I want to change android application localization Arabic - English.
but when I change language to Arabic it's changed all numbers to Arabic so the app crashed I want to change language to Arabic and prevent change numbers language from English.
Locale locale = new Locale(AppConfig.Language);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = "ar";
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.activity_main);
when I want to use gps get location it's return numbers in arabic
how I can prevent it to change numbers language ??
I know this answer is too late but it can help someone in the future.
I was struggling with it for some days but I found an easy solution.
just set the country as the second parameter.because some countries use Arabic numeral and others use the so-called Hindu Numerals
Locale locale = new Locale(LanguageToLoad,"MA");//For Morocco to use 0123...
or
Locale locale = new Locale(LanguageToLoad,"SA");//For Saudi Arabia to use ٠١٢٣...
Founded Here
there is a complement so you don't have to change the whole code.
There's such issue in Google's bugtracker: Arabic numerals in arabic language intead of Hindu-Arabic numeral system
If particularly Egypt locale doesn't work due to some customer's issue(I can understand it), then you can format your string to any other western locales. For example:
NumberFormat nf = NumberFormat.getInstance(new Locale("en","US")); //or "nb","No" - for Norway
String sDistance = nf.format(distance);
distanceTextView.setText(String.format(getString(R.string.distance), sDistance));
If solution with new Locale doesn't work at all, there's an ugly workaround:
public String replaceArabicNumbers(String original) {
return original.replaceAll("١","1")
.replaceAll("٢","2")
.replaceAll("٣","3")
.....;
}
(and variations around it with Unicodes matching (U+0661,U+0662,...). See more similar ideas here)
Upd1:
To avoid calling formatting strings one by one everywhere, I'd suggest to create a tiny Tool method:
public final class Tools {
static NumberFormat numberFormat = NumberFormat.getInstance(new Locale("en","US"));
public static String getString(Resources resources, int stringId, Object... formatArgs) {
if (formatArgs == null || formatArgs.length == 0) {
return resources.getString(stringId, formatArgs);
}
Object[] formattedArgs = new Object[formatArgs.length];
for (int i = 0; i < formatArgs.length; i++) {
formattedArgs[i] = (formatArgs[i] instanceof Number) ?
numberFormat.format(formatArgs[i]) :
formatArgs[i];
}
return resources.getString(stringId, formattedArgs);
}
}
....
distanceText.setText(Tools.getString(getResources(), R.string.distance, 24));
Or to override the default TextView and handle it in setText(CharSequence text, BufferType type)
public class TextViewWithArabicDigits extends TextView {
public TextViewWithArabicDigits(Context context) {
super(context);
}
public TextViewWithArabicDigits(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void setText(CharSequence text, BufferType type) {
super.setText(replaceArabicNumbers(text), type);
}
private String replaceArabicNumbers(CharSequence original) {
if (original != null) {
return original.toString().replaceAll("١","1")
.replaceAll("٢","2")
.replaceAll("٣","3")
....;
}
return null;
}
}
I hope, it helps
It is possible to set the locale for the individual TextView or elements that extend it in your app. see http://developer.android.com/reference/android/widget/TextView.html#setTextLocale(java.util.Locale) for more information
UPDATE
You can use the following method to parse the number to the locale you want
public static String nFormate(double d) {
NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
nf.setMaximumFractionDigits(10);
String st= nf.format(d);
return st;
}
Then you can parse number to double again
The best and easy way to do is keep the number in all string file as it is , in all the localization strings. Or you need to translate each number string into numbers
I have had the same problem, the solution was to concatenate the number variable with an empty string.
For example like this :
public void displayPoints(int:points){
TextView scoreA = findViewById(R.id.score_id);
scoreA.setText(""+points);
}
I used this
scoreA.setText(""+points);
instead of this
scoreA.setText(String.format("%d",points));
this will even give you a warning that hardcoded text can not be properly translated to other languages, which exactly what we want here :) .

How to change locale to use Latin Serbian (instead of Cyrillic Serbian)

The Serbian language has Latin and Cyrillic alphabets. In Android's Date and Time Picker widgets, the displayed alphabet for Serbian locales seems to be Cyrillic, as seen here.
I wanted to change the locale so that the android widgets are using the Latin Serbian alphabet.
The current language/country code (yielding Cyrillic) are sr and RS respectively. Therefore, my setLocale function is called as
setLocale("sr", "RS");
This is the part im not sure about - according to localeplanet.com, the local code for latin serbian is sr_Latn_RS. However, I tried both
setLocale("sr_Latn", "RS");
//and
setLocale("sr_Latn_RS", "RS");
neither of which work (no change occurs, default to english). According to the Android documentation, it looks like setLocale expects two letter codes.
The language codes are two-letter lowercase ISO language codes (such
as "en") as defined by ISO 639-1. The country codes are two-letter
uppercase ISO country codes (such as "US") as defined by ISO 3166-1.
The variant codes are unspecified.
So how do I specify a Latin serbian locale code? Or does it not exist?
The previous answer works well if you only support Lollipop or above. However, if you're coding in Serbian a lot of your user base probably won't have it. Here's a solution that works for old and new versions.
private static Locale serbianLatinLocale(){
Locale locale = null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
for (Locale checkLocale : Locale.getAvailableLocales()) {
if (checkLocale.getISO3Language().equals("srp") && checkLocale.getCountry().equals("LATN") && checkLocale.getVariant().equals("")) {
locale = checkLocale;
}
}
} else {
locale = new Locale.Builder().setLanguage("sr").setRegion("RS").setScript("Latn").build();
}
return locale;
}
For getting latin locale I first used code below.
new Locale.Builder().setLanguage("sr").setRegion("RS").setScript("Latn").build();
But this solution didn't work on my Android 5.1.1 device (it was still in cyrillic). So I removed setting of region like this:
new Locale.Builder().setLanguage("sr").setScript("Latn").build();
And you have to put your string for serbian resources in b+sr+Latn folder.
Please search for your query before posting a question. It may be answered in some other related form.
Locale newLocale = new Locale("sr","RS");
Configuration config = new Configuration();
config.setLocale(newLocale);
// using this to reference my Activity
this.getBaseContext().getResources().updateConfiguration(config, this.getBaseContext().getResources().getDisplayMetrics());
i found these two answers suitable to your query
android custom date-picker SO and locale from english to french.
EDIT
Locale[] locales = Locale.getAvailableLocales();
for(Locale locale : locales){
if(locale.getCountry().equalsIgnoreCase("RS")
&& locale.getScript().equalsIgnoreCase("Latn"))
{
Configuration config = new Configuration();
config.setLocale(locale);
// using this to reference my Activity
this.getBaseContext().getResources().updateConfiguration(config, this.getBaseContext().getResources().getDisplayMetrics());
break;
}
}
I know there will be an efficient way to do it, however you may get the direction that you need to get the list of available locales and get the locale you desire. Hope it helps
EDIT-2 (Final)
you can construct the locale using:
Locale locale = new Locale.Builder().setLanguage("sr").setRegion("RS").setScript("Latn").build();
setLocale(locale);
Can you please use below one ?
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Resources res = this.getResources();
Configuration conf = res.getConfiguration();
boolean isLatinAlphabet = PreferenceManager.getDefaultSharedPreferences(this);
if(conf.locale.getLanguage().equals("sr") && isLatinAlphabet) {
conf.locale = new Locale("sr", "YourContryCode");
res.updateConfiguration(conf, res.getDisplayMetrics());
}
}
}
Note: Replace your YourContryCode in conf.locale = new Locale("sr", "YourContryCode"); line.
Manifest.xml:
<application
android:name=".MyApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/application_name"
android:theme="#style/AppTheme">
...
</application>
Hope this will help you.

If the language is english then use an another link than if it's german

how does the if condition look like?
if(Locale.getDefault().equals("English")){
Log.i("Language","Englisch");
} else if(Locale.getDefault().equals("Deutsch")){
Log.i("Language","Deutsch");
}
This won't work
Locale.getDefault() will return a static Locale Object, not a String. So calling Locale.getDefault().equals("English") will not work.
Try this:
String language = Locale.getDefault().getLanguage();
if (language.equals("en"))
{
// Use English link
}
else if (language.equals("de"))
{
// Use German link
}
public String getLanguage ()
Added in API level 1
Returns the language code for this Locale or the
empty string if no language was set.
Or:
String language = Locale.getDefault().getDisplayLanguage();
if (language.equals("English"))
{
// Use English link
}
else if (...) { ....
public final String getDisplayLanguage ()
Added in API level 1 Equivalent to
getDisplayLanguage(Locale.getDefault()).
Here are other possibilities:
Locale.getDefault().getLanguage() ---> en
Locale.getDefault().getISO3Language() ---> eng
Locale.getDefault().getCountry() ---> US
Locale.getDefault().getISO3Country() ---> USA
Locale.getDefault().getDisplayCountry() ---> United States
Locale.getDefault().getDisplayName() ---> English (United States)
Locale.getDefault().toString() ---> en_US
Locale.getDefault().getDisplayLanguage()---> English
Documentation here.
Locale.getDefault returns a Locale, not a String. If you want to know more about that locale you call getLanguage and getCountry on the Locale. Look up ISO code for language and country.
Usually, in android you solve something like this by different resources. Under res/values-en/ and res/values-de/ you can define language specific strings.

Using text to speech APIs in android application

I want to use TTS (Text to Speech) APIs in my android application.Now i have one quetions - Is it support TURKISH language ?
I also want to highlight word in textview when that perticular word is being spoke.
How can i do it ?
Can anybody help me ?
Thanks in advance !
Does it support TURKISH language
This may vary on different handsets/flavours of Android. You can check it out for yourself using the
mTTS.isLanguageAvailable(new Locale("tr", "TUR"));
I also want to highlight word in textview when that particular word is being spoke.
Well you have a TextToSpeech.OnUtteranceCompletedListener(), to use this you have to speak() each word, one at a time.
The TTS engine that ships with the Android platform supports a number of languages: English, French, German, Italian and Spanish. Also, depending on which side of the Atlantic you are on, American and British accents for English are both supported.
http://developer.android.com/resources/articles/tts.html
You should use Locale type variable.
final Locale locale = new Locale("tr", "TR");
tts = new TextToSpeech(getApplicationContext(), new
TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(locale);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.d("class name", "tts error ");
}
} else {
Log.d("class name", "tts error ");
}
}
});
tts.speak("write here what you want in Turkish", TextToSpeech.QUEUE_FLUSH, null);

Categories

Resources