How to get language by country, not the default one? - android

I'm trying to get the country language of the user, not the selected one on the phone.
For example:
I'm building an English learning app, but in my phone I've set language to English for learning purposes, and it doesn't translate because it thinks that my language is English, but I live in brazil, I want it to find that my language is Portuguese. to get languages by especific location.
I have tried some codes, but not seems to work.
I have many users in my app that have English language on phone, so they are facing the same problem.
var currentLanguage: String = Locale.getDefault().language
var language = this.getResources().getConfiguration().getLocales().get(0).language
They both give me the same value, that my language is english, and if I get the country it says I'm in US.
EDIT:
I'm able to get the country code with it:
var tm = this.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
var countryCodeValue = tm.networkCountryIso
It returns br, but how can I get the language from this tag?
There is something like:
countryCodeValue.language
?

Well you have it there in your own description of the problem. You want to get the language based on the country the user is in. So you need to first get the country where the user is in. So it's a location problem.
There are several options. One is to get the user's location using the last known location of the user.
Docs: https://developer.android.com/training/location/retrieve-current
The problem here is you need to then transform coordinates to country. There are some API's for this, Google maps has one.
Maybe an easier approach is to use the TelephonyManager to get the country code of the user. This also has a problem because it relies on having a sim card.
Finally you need to transform that country to a language. But you can do that with the Locale class.
IMHO, it would be easier to give your users a selector for the language, that way they can decide what language to use instead of you choosing for them based on some algorithm.
Update:
It's not that straight forward to get the language of a Country. Basically some countries have multiple official languages for example. There are other questions addressing this issue. But in short, you either have a static file mapping from country to language or you iterate over the available Locales and choose one of the languages for the country.
Here are other questions:
If you have the ISO country code `US`, `FR`, how do you get the Locale code (`Locale.US`, `Locale.FRANCE`)?
Getting default language from country code in Java
How to get the language code based on country code in java

Well guys, I did it, and its working almost as I wanted it to be.
I'll have a little work to do it for too much countries. If someone have a better Idea, I'd be glad to know. Thanks. Maybe it can help someone.
var tm = ctx.getSystemService(AppCompatActivity.TELEPHONY_SERVICE) as TelephonyManager
var countryCodeValue = tm.networkCountryIso
fun getLanguage(country: String) : String{
var current : String
when{
country.contains("br") && Locale.getDefault().language.equals("en") -> current = Locale.forLanguageTag("pt").toString()
country.contains("in") && Locale.getDefault().language.equals("en") -> current = Locale.forLanguageTag("hi").toString()
country.contains("pk") && Locale.getDefault().language.equals("en") -> current = Locale.forLanguageTag("ur").toString()
else -> current = Locale.getDefault().language
}
return current
}
var lang = getLanguage(countryCodeValue)
var tradOpt = TranslatorOptions.Builder()
.setSourceLanguage(TranslateLanguage.ENGLISH)
.setTargetLanguage(TranslateLanguage.fromLanguageTag(lang).toString())
.build()

Related

Change currency symbol automatically based on current location

I'm using the following code to retrieve the user's local currency symbol:
public static String getCurrencySymbol() {
Currency currency = Currency.getInstance(Locale.getDefault());
return currency.getSymbol();
}
However, one of my users moved from UK to the US and his currency symbol is still showing as the British Pound. Is there some way to make it show as a US Dollar symbol ($) now that's he's moved to the US?
I think Locale.getDefault() is just related to the language settings on the phone and has nothing to do with the current location (of the phone). That's why the actual Locale did not change, even though your User moved to the US.
A possible solution would be to add a settings option in your App, so the user can change his currency when needed. This option then would just change your application wide Locale used for the currency.

Best Practice of multi language Android App

I'm making an android app with multi-language support.
I have around 30 language to support my app.
I'm playing within 2 Case.
case 1 . First case is creating values folder of every language in res folder.
case 2. Second case Get every language content with a key from server
e.g. TXT_HELLO = HELLO if user choose English
TXT_HELLO. = HOLA. if user choose Spanish
Suppose from language list I select Spanish during language change
then server give me list of every Spanish content with a same key
[Key] = [Value]
e.g. TXT_HELLO = Hola
TXT_GOOD = Bueno
& then I save this value with key is session & all key also in my Constant class
Similarly In Case if I select English:
[Key] = [Value]
e.g. TXT_HELLO = Hello
TXT_GOOD = good. as Soon
This is how my kotlin code work.
fun getLanguageValue(key : String)->{
return sharedPre.getString(key)
}
txtViewHello.text = getLanguageValue(MyConstant.TXT_HELLO)
cons and pros of case 1 .
pros : It handle by system and good memory management
cons : Language only can add on new release apk. if some word is wrong then can't be correct without release.
cons and pros of case 2 .
pros : if some word is wrong then can correct online. No need to release new APK or can add more language at any time.
cons : It handle by me and initialization of objects is more complex.
So please suggest me what is best approach & what is best practice to change language.
You could attempt to write your own language switcher that does this, but I'd advise against it. This is basically fighting the system, and is very hard to handle properly.
The best way to handle multiple languages is to use resource qualifiers, and make the system do the hard work for you. It will also match the user's expectation that your app will be in the same language as the entire rest of their phone.

String is read as number rather than reading it digit by digit when talk back is on in android

I have a string "9039662543", and when talk back is on, this string is read as "nine million...." in 4.3 android devices, above 4.3 devices its working fine, by reading "nine zero three...". What should I do to fix this?
I'm assuming this is a phone number? I can't tell because there is no formatting. Which is the heart of the problem. There are multiple fixes for this.
A: Leave it alone. TalkBack users have the option of parsing elements by view, paragraph, sentence, word, character, etc. If a user can't tell it's a phone number by the context, you need more context. The number itself is fine!
B: Format it better. (903)-966-2542 vs 9039662543, without any additional context, are two different pieces of information. It may still read out as something like "Parentheses nine-hundread and three........" but it will be more obvious it is a phone number, and the chunks are easy to keep track of. Sorry I dno't have a pre 4.3 device to check out what the actual announcement is.
C: Override the content description. If the text representation is:
Text: 9039662543
Content Description: 9 0 3 9 6 6 2 5 4 3
I recommend against this approach. These two values are not the same. Just because you are uncomfortable with the announcement doesn't mean a TalkBack user would be. As you get accustomed to using TalkBack you get accustom to switching to different text parsing modes. A user who doesn't care about the phone number would be frustrated by the slower read out of the separated version. Leave them the option of ignoring it, and having it blow by quickly in the more compressed form. Also, informatively, if there is no context those two numbers don't really represent the same thing. The solution in this case is provide this context NOT to change the presentation. Separate is NOT equal.
For EditText, add a space between characters and set this text in Accessibility Node Info.
ViewCompat.setAccessibilityDelegate(editText,object : AccessibilityDelegateCompat(){
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.text = editText.text.toString().replace(".".toRegex(),"$0 ")
}
})
While I see multiple people recommending what ChrisCM has posted. I see that the default contacts application does this differently.
The default contact application reads the phone number digit-by-digit. It also does a little more than that and it can be reused. The API that is used is:
https://developer.android.com/reference/android/telephony/PhoneNumberUtils.html#createTtsSpan(java.lang.String)
The details of how it works could be found here :
https://android.googlesource.com/platform/frameworks/base/+/master/telephony/java/android/telephony/PhoneNumberUtils.java
//add extra space to text and set that text as contentDescription
textView.setText(readbleText);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < readbleText.length(); i++) {
builder.append(readbleText.charAt(i));
builder.append("\u00A0");
}
textView.setContentDescription(builder);
Make sure the input type on the edittext is phone and not number:
android:inputType="phone"
and not:
android:inputType="number"
I know it's already answered but inspired by this answer
I wrote an extension function for textView (in Kotlin of course ) which can be re-used as a utility function overall by those who might have this problem.
fun TextView.separateText() {
val textView = this
ViewCompat.setAccessibilityDelegate(textView, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(
host: View,
info: AccessibilityNodeInfoCompat
) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.text = textView.text.toString().replace(".".toRegex(), "$0 ")
}
})
}
PS: I was not able to post this under his/her answer, because I do not enough reputation.
You can add zero-width non-breaking space characters "\ufeff" to separate the numbers invisibly. It will read the number as digits. Do refer the comment in the below link for more details
How to change Android Talkback in case of App name

How do I get the local Currency Code for my android app?

I'm integrating my android app with Google analytics v4. I'm in Argentina, so my currency code is "ARS", not "USD". I need to specify the local currency code (of any other country), otherwise it sends wrong information.
For example, the price tag of an article says it costs "9,32 ARS", if I don't specify the currency code it sends "9,32 USD". Thanks
// Send Item
googleTracker.send(new HitBuilders.ItemBuilder()
.setTransactionId(purchase.getOrderId())
.setName(purchase.getPackageName())
.setSku(purchase.getSku())
.setCategory("Coins")
.setPrice(skuDetails.getPriceMicros())
.setQuantity(1)
.setCurrencyCode(????)
.build());
You can try like this
Currency currency = Currency.getInstance(Locale.getDefault());
String currencyCode = currency. getCurrencyCode();
I actually could get it working using this answer here: SOLUTION
Google added to its API a new field which is "price_currency_code", to getSkuDetails, which allows us to get the currency code of a transaction. You must edit SkuDetails.java as this answer shows.
According to the measurement protocol definition for currency code you need to pass a valid ISO 4217 currency code to HitBuilders.ItemBuilder.setCurrencyCode() call. Android provides Currency class that support ISO 4217. You should be able to use it to compose the parameter you need for the setCurrencyCode call.
In android many ways to get local currency.
But the bad thing is, In some cases, we got device-specific issues.
val currency = Currency.getInstance(Locale.getDefault())
currency.currencyCode
currency.symbol
The above code gives the currency code a and symbol, But have an issue, If we change the phone locale, the currency also changed.
We have another way to get local currency, if we change the Phone locale, the local currency is not affected
Currency.getInstance(Locale("",tm.networkCountryIso)).currencyCode.toString()
Currency.getInstance(Locale("",tm.networkCountryIso)).symbol.toString()

check mobile number valid or not through country code

I have contact like "+919672525253".Now i extract the country code like "91" from that number.Now if number is like "9672525253" and if i extract the country code then it will give me "967".So after extracting the country code how can i check that remaining number is valid mobile number for that country code or not?
EDIT
If any body know the mobile number length country wise then also i can solve this problem.like in india 10 digits.
You pretty much can't. For example in the US mobile numbers and landline numbers are indistinguishable, they have normal area codes just like landline numbers. Even if it were possible every country does it differently and it is also constantly changing as numbers run out new prefixes are added and things change and their is no pattern you could match against or database you could do a lookup against.
Take a look at libPhoneNumber (bundled in ICS) which can help validating a phone number (see PhoneNumberUtils).
There's a MobileType you can get after validation but as stated in the source and by Ben, in some region this will not work.
EDIT:
Some validation code (here we need to check the phone is a valid one assuming it's a french one):
boolean isValid = false;
PhoneNumber number = null;
try {
number = this.phoneUtil.parse(phone, "FR"); // phone is number in internationnal format "+xxxxxx"
isValid = this.phoneUtil.isValidNumber(number);
} catch (final NumberParseException e) {
// ...
}
isValid // is the phone number valid according to the library?
this.phoneUtil.getRegionCodeForNumber(number); // this gets the country code of the phone as found by the library (for example "US", "CH", "GB", ...)
This works for us but you'll need to try it to see if it suit your need.

Categories

Resources