Number formatting Android 5.0 - android

I've noticed a strange bug while looking at my app on an Android device running 5.0.
On pre 5.0 devices my app will add commas into numbers where necessary. e.g "1,234" or "100,000"
On 5.0 devices the same code displays these numbers as "1234" or "100000". Has any one else noticed this?
I have included my code to format the numbers below - I'm not to sure what needs to change for lollipop devices to show the correct format.
public static String formatNumber(Integer number, String prefix) {
if (prefix == null) {
prefix = Constants.PREFIX_SYMBOL;
}
StringBuilder stringBuilder = new StringBuilder(prefix);
NumberFormat numberFormatter = NumberFormat.getIntegerInstance(new Locale("en_UK"));
stringBuilder.append("").append(numberFormatter.format(number));
return stringBuilder.toString();
}

So I think the solution to this is as follows
public static String formatNumber(Integer number, String prefix) {
if (prefix == null) {
prefix = Constants.PREFIX_SYMBOL;
}
StringBuilder stringBuilder = new StringBuilder(prefix);
NumberFormat numberFormatter = NumberFormat.getIntegerInstance();
stringBuilder.append("").append(numberFormatter.format(number));
return stringBuilder.toString();
}
Removing the Locale from the NumberFormat.getIntegerInstance(); call seems to do the trick. This is added in as some Locales will use non-ASCII decimal digits when formatting integers as specified here. I do not think that this is the case for the regions that my app is available in so it should do the trick.
EDIT:
NumberFormat numberFormatter = NumberFormat.getIntegerInstance(new Locale("en_UK"));
can be replaced with
NumberFormat numberFormatter = NumberFormat.getIntegerInstance(new Locale("en", "GB"));
This will prevent the default locales from using non-ASCII decimal digits.

To group digits you could use DecimalFormat instead of NumberFormat:
DecimalFormat formatter = new DecimalFormat("###,###");
will do the trick.

Related

How to get last 4 digit of number in android?

I have an app which contain mobile number edit text in which user can edit mobile number and I have to send two request to server like:- mobile number and mssdn,mobile number(which is full lenghth ) and mssdn(which contain mobile number last 4 digit).How can I do that
Try this. Check for length greater than 4 before calling subString to avoid IndexOutOfBounds Exception.
EditText mEdtPhoneNumber = (EditText) findViewById(R.id.edtPhoneNumber);
String phoneNumber = mEdtPhoneNumber.getText().toString().trim();
String strLastFourDi = phoneNumber.length() >= 4 ? phoneNumber.substring(phoneNumber.length() - 4): "";
Also what is mssdn?? Is it msisdn??
Use the modulus (%) operator:
To get the last digit: use number % 10
To get the last 2 digits: use number % 100
and so on
For example:
42455%10000 = 2455
You could do something like this:
EditText phoneNumberEditText = (EditText) findViewById(R.id.phoneNumberEditText);
String phoneNumber = phoneNumberEditText.getText().toString();
String lastFourDigits = phoneNumber.substring(phoneNumber.length() - 4);
you should use regex because this will only give you result if the last four letters are actually numbers on the other hand the substring function simply give you last four letters no matter they are numbers or characters. e.g 4344sdsdss4 will give you dss4 which is clearly not a part of phone number
String str="4444ntrjntkr555566";
Pattern p = Pattern.compile("(\\d{4})$");
Matcher m = p.matcher(str);
if (m.find()) {
System.out.println(m.group(m.groupCount()));
}
this will produce 5566
Working
//d mean digits
{4} for fix length as 4
$ mean at the end
List<Integer> f(String str){
ArrayList<Integer> digits = new ArrayList<>();
if (null == str || str.length() < 4){
Log.i(LOG_TAG, "there are less than 4 digits");
return digits;
}
String digitsStr = str.substring(str.length() - 4);
for (char c : digitsStr.toCharArray()){
try {
Integer digit = Integer.parseInt(String.valueOf(c));
digits.add(digit);
} catch (Exception e){
continue;
}
}
return digits;
}
We can also use a new method introduced in kotlin: takeLast(n)
fun getLastDigit(data: String, n:Int): String {
return if(data.length > n){
data.takeLast(n)
}else {
""
}
}

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 get text with using substring

I try to get only this part "9916-4203" in "Region Code:9916-4203 " in android. How can I do this?
I tried below code, I used substring method but it doesn't work:
firstNumber = Integer.parseInt(message.substring(11, 19));
If you know that string contains "Region Code:" couldn't you do a replace?
message = message.replace("Region Code:", "");
Assumed that you have only one phone number in your String, the following will remove any non-digit characters and parse the resulting number:
public static int getNumber(String num){
String tmp = "";
for(int i=0;i<num.length();i++){
if(Character.isDigit(num.charAt(i)))
tmp += num.charAt(i);
}
return Integer.parseInt(tmp);
}
Output in your case: 99164203
And as already mentioned, you won't be able to parse any String to Integer in case there are any non-digit characters
Im going to guess that what you want to extract is the full region code text minus the title. So maybe using regex would be a good simple fit for you?
String myString = "Region Code:9916-4203";
String match = "";
String pattern = "\:(.*)";
Pattern regEx = Pattern.compile(pattern);
Matcher m = regEx.matcher(myString);
// Find instance of pattern matches
Matcher m = regEx.matcher(myString);
if (m.find()) {
match = m.group(0);
}
Variable match will contain "9916-4203"
This should work for you.
Java code sourced from http://android-elements.blogspot.in/2011/04/regular-expressions-in-android.html
In Java the substring() method works with the first parameter being inclusive and the second parameter being exclusive. Meaning "Hello".substring(0, 2); will result in the string He.
In addition to excluding the parsing of something that isn't a number like #Opiatefuchs mentioned, your substring method should instead be message.substring(12, 21).

DecimalFormat("#0.000") doesn't format the right way like 1.321 instead of this it delievers 1,321

I want to get a Double with 3 decimalplaces. I do this:
String sAveragePrice;
Double dAveragePrice = holePrice/(allPrices.size()); // delivers 1.3210004
DecimalFormat threeZeroes = new DecimalFormat("#0.000");
sAveragePrice = threeZeroes.format(dAveragePrice); // delivers then 1,321
After formatting I dont get a 1.321 but 1,321. And the 1,321 throws a NumberformatException later. This is when it is thrown:
Double priceInt = Double.parseDouble(sAveragePrice); // throws NumberFormatException
The strange thing is, I have this code till 3 weeks and it didn't make any problem. But today when I have started my app again it gets problem with it. But I didn't have changed anything.
Can anybody help me? I also tried this:
NumberFormat format = NumberFormat.getNumberInstance();
format.setMinimumFractionDigits(3);
format.setMaximumFractionDigits(3);
sAveragePrice = format.format(dAveragePrice);
But it also delivers me a "," instead of a "." for double.
Try using a locale for you number format.
Number format = NumberFormat.getNumberInstance(Locale.ITALIAN);
Java SDK has a limited number of predefined locale settings, so for other locales (e.g., for Russian), you can use the following snippet:
Number format = NumberFormat.getNumberInstance(new Locale("ru", "RU"));
Number format = NumberFormat.getNumberInstance(new Locale("it", "IT")); // etc...
this sample code may help you...
Locale locale = Locale.getDefault();
// set Locale.US as default
Locale.setDefault(Locale.US);
DecimalFormat decimalFormat = new DecimalFormat("##.000");
double d = 14.5589634d;
String format = decimalFormat.format(d);
System.out.println(format);// prints 14.559
// back to default locale
Locale.setDefault(locale);
Have a look at this SO question
How to change the decimal separator of DecimalFormat from comma to dot/point?
Basically your output will be Locale specific, so if you have a Locale of Frame then it will be different to a Locale of the US.
try
NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
Use this type of formatting
use # instead of 0. It is the correct format to declare your pattern
String sAveragePrice;
Double dAveragePrice = holePrice/(allPrices.size());
DecimalFormat threeZeroes = new DecimalFormat("#.###");
sAveragePrice = threeZeroes.format(dAveragePrice);
Hope it will help you

How to format a Double value properly with decimal separator?

I have an application that uses thousands separator (,) and decimal separator (.), I used this app on 2 tablets with the same languages (Español) on their configuration and when I do some process with numbers like 15,000.00 on the first one the answer was correct but in the second tablet the number changes to 15,00. I changed the language of the second to English, and it works, but how can i set this number format on code?
Sorry about the errors this is not my native language.
Thanks for the help
You could format a double value in code like this:
/**
* format a number properly
* #param number
* #return
*/
public String formatDecimal(double number) {
DecimalFormat nf = new DecimalFormat("###.###.###.##0,00");
// or this way: nf = new DecimalFormat("###,###,###,##0.00");
String formatted = nf.format(number);
return formatted;
}
And then set it to a TextView:
mytextview.setText("MyDouble: " + formatDecimal(somedouble));
You could format using
NumberFormat nf = NumberFormat.getInstance(new Locale("es", "MX")); //for example
But beware because depending on the locale, even if is the same language but different country the decimal char and grouping char my change, for example
NumberFormat nf = NumberFormat.getInstance(new Locale("es", "CO")); //displays 15.000,00
You can get an instance for a specific locale as specified by the android docs:
NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
However, you should not change the locale when displaying stuff to the user imho.

Categories

Resources