Omar
Omar

Reputation: 269

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 ??

Upvotes: 23

Views: 11094

Answers (5)

Omar
Omar

Reputation: 643

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 :) .

Upvotes: 0

Canato
Canato

Reputation: 3978

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

Upvotes: 4

Ajay Venugopal
Ajay Venugopal

Reputation: 1710

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

Upvotes: 0

Jwdsoft
Jwdsoft

Reputation: 461

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 ٠١٢٣...

Upvotes: 22

Bisho Adam
Bisho Adam

Reputation: 191

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

Upvotes: 1

Related Questions